diff --git a/package.json b/package.json index 1066262b34267..6390e367c9187 100644 --- a/package.json +++ b/package.json @@ -237,11 +237,14 @@ "@kbn/core-preboot-server-mocks": "link:bazel-bin/packages/core/preboot/core-preboot-server-mocks", "@kbn/core-saved-objects-api-browser": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-api-browser", "@kbn/core-saved-objects-api-server": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-api-server", + "@kbn/core-saved-objects-base-server-internal": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-base-server-internal", + "@kbn/core-saved-objects-base-server-mocks": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-base-server-mocks", "@kbn/core-saved-objects-browser": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-browser", "@kbn/core-saved-objects-browser-internal": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-browser-internal", "@kbn/core-saved-objects-browser-mocks": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-browser-mocks", "@kbn/core-saved-objects-common": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-common", "@kbn/core-saved-objects-server": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-server", + "@kbn/core-saved-objects-utils-server": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-utils-server", "@kbn/core-test-helpers-deprecations-getters": "link:bazel-bin/packages/core/test-helpers/core-test-helpers-deprecations-getters", "@kbn/core-test-helpers-http-setup-browser": "link:bazel-bin/packages/core/test-helpers/core-test-helpers-http-setup-browser", "@kbn/core-theme-browser": "link:bazel-bin/packages/core/theme/core-theme-browser", @@ -894,11 +897,14 @@ "@types/kbn__core-public-internal-base": "link:bazel-bin/packages/core/public/internal-base/npm_module_types", "@types/kbn__core-saved-objects-api-browser": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-api-browser/npm_module_types", "@types/kbn__core-saved-objects-api-server": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-api-server/npm_module_types", + "@types/kbn__core-saved-objects-base-server-internal": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-base-server-internal/npm_module_types", + "@types/kbn__core-saved-objects-base-server-mocks": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-base-server-mocks/npm_module_types", "@types/kbn__core-saved-objects-browser": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-browser/npm_module_types", "@types/kbn__core-saved-objects-browser-internal": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-browser-internal/npm_module_types", "@types/kbn__core-saved-objects-browser-mocks": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-browser-mocks/npm_module_types", "@types/kbn__core-saved-objects-common": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-common/npm_module_types", "@types/kbn__core-saved-objects-server": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-server/npm_module_types", + "@types/kbn__core-saved-objects-utils-server": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-utils-server/npm_module_types", "@types/kbn__core-server-internal-base": "link:bazel-bin/packages/core/server/internal-base/npm_module_types", "@types/kbn__core-test-helpers-deprecations-getters": "link:bazel-bin/packages/core/test-helpers/core-test-helpers-deprecations-getters/npm_module_types", "@types/kbn__core-test-helpers-http-setup-browser": "link:bazel-bin/packages/core/test-helpers/core-test-helpers-http-setup-browser/npm_module_types", diff --git a/packages/BUILD.bazel b/packages/BUILD.bazel index a9a0377b679dd..b084fa8617929 100644 --- a/packages/BUILD.bazel +++ b/packages/BUILD.bazel @@ -102,11 +102,14 @@ filegroup( "//packages/core/preboot/core-preboot-server:build", "//packages/core/saved-objects/core-saved-objects-api-browser:build", "//packages/core/saved-objects/core-saved-objects-api-server:build", + "//packages/core/saved-objects/core-saved-objects-base-server-internal:build", + "//packages/core/saved-objects/core-saved-objects-base-server-mocks:build", "//packages/core/saved-objects/core-saved-objects-browser-internal:build", "//packages/core/saved-objects/core-saved-objects-browser-mocks:build", "//packages/core/saved-objects/core-saved-objects-browser:build", "//packages/core/saved-objects/core-saved-objects-common:build", "//packages/core/saved-objects/core-saved-objects-server:build", + "//packages/core/saved-objects/core-saved-objects-utils-server:build", "//packages/core/test-helpers/core-test-helpers-deprecations-getters:build", "//packages/core/test-helpers/core-test-helpers-http-setup-browser:build", "//packages/core/theme/core-theme-browser-internal:build", @@ -375,11 +378,14 @@ filegroup( "//packages/core/preboot/core-preboot-server:build_types", "//packages/core/saved-objects/core-saved-objects-api-browser:build_types", "//packages/core/saved-objects/core-saved-objects-api-server:build_types", + "//packages/core/saved-objects/core-saved-objects-base-server-internal:build_types", + "//packages/core/saved-objects/core-saved-objects-base-server-mocks:build_types", "//packages/core/saved-objects/core-saved-objects-browser-internal:build_types", "//packages/core/saved-objects/core-saved-objects-browser-mocks:build_types", "//packages/core/saved-objects/core-saved-objects-browser:build_types", "//packages/core/saved-objects/core-saved-objects-common:build_types", "//packages/core/saved-objects/core-saved-objects-server:build_types", + "//packages/core/saved-objects/core-saved-objects-utils-server:build_types", "//packages/core/test-helpers/core-test-helpers-deprecations-getters:build_types", "//packages/core/test-helpers/core-test-helpers-http-setup-browser:build_types", "//packages/core/theme/core-theme-browser-internal:build_types", diff --git a/packages/core/saved-objects/core-saved-objects-base-server-internal/BUILD.bazel b/packages/core/saved-objects/core-saved-objects-base-server-internal/BUILD.bazel new file mode 100644 index 0000000000000..d64f0bb533a0f --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/BUILD.bazel @@ -0,0 +1,111 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") + +PKG_DIRNAME = "core-saved-objects-base-server-internal" +PKG_REQUIRE_NAME = "@kbn/core-saved-objects-base-server-internal" + +SOURCE_FILES = glob( + [ + "src/**/*.ts", + ], + exclude = [ + "**/*.test.*", + "**/*.stories.*", + ], +) + +SRCS = SOURCE_FILES + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "package.json", +] + +RUNTIME_DEPS = [ + "@npm//lodash", + "@npm//semver", + "//packages/kbn-config-schema", + ### test dependencies + "//packages/kbn-logging-mocks", + "@npm//@hapi/boom", +] + +TYPES_DEPS = [ + "@npm//@types/node", + "@npm//@types/jest", + "@npm//@types/lodash", + "@npm//@types/semver", + "//packages/kbn-logging:npm_module_types", + "//packages/kbn-config-schema:npm_module_types", + "//packages/core/base/core-base-server-internal:npm_module_types", + "//packages/core/saved-objects/core-saved-objects-server:npm_module_types", + "//packages/core/saved-objects/core-saved-objects-utils-server:npm_module_types", +] + +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), + root_input_dir = "src", +) + +ts_config( + name = "tsconfig", + src = "tsconfig.json", + deps = [ + "//:tsconfig.base.json", + "//:tsconfig.bazel.json", + ], +) + +ts_project( + name = "tsc_types", + args = ['--pretty'], + srcs = SRCS, + deps = TYPES_DEPS, + declaration = True, + declaration_map = True, + emit_declaration_only = True, + out_dir = "target_types", + root_dir = "src", + tsconfig = ":tsconfig", +) + +js_library( + name = PKG_DIRNAME, + srcs = NPM_MODULE_EXTRA_FILES, + deps = RUNTIME_DEPS + [":target_node"], + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [":" + PKG_DIRNAME], +) + +filegroup( + name = "build", + srcs = [":npm_module"], + visibility = ["//visibility:public"], +) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [":npm_module_types"], + visibility = ["//visibility:public"], +) diff --git a/packages/core/saved-objects/core-saved-objects-base-server-internal/README.md b/packages/core/saved-objects/core-saved-objects-base-server-internal/README.md new file mode 100644 index 0000000000000..0315d68aca7b0 --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/README.md @@ -0,0 +1,4 @@ +# @kbn/core-saved-objects-base-server-internal + +This package contains the base parts of the server-side savedObjects internal implementation, +used by all the other internal server-side savedObjects packages. \ No newline at end of file diff --git a/packages/core/saved-objects/core-saved-objects-base-server-internal/jest.config.js b/packages/core/saved-objects/core-saved-objects-base-server-internal/jest.config.js new file mode 100644 index 0000000000000..384625b895fcd --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/jest.config.js @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +module.exports = { + preset: '@kbn/test/jest_node', + rootDir: '../../../..', + roots: ['/packages/core/saved-objects/core-saved-objects-base-server-internal'], +}; diff --git a/packages/core/saved-objects/core-saved-objects-base-server-internal/package.json b/packages/core/saved-objects/core-saved-objects-base-server-internal/package.json new file mode 100644 index 0000000000000..ff4b901f49056 --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/package.json @@ -0,0 +1,7 @@ +{ + "name": "@kbn/core-saved-objects-base-server-internal", + "private": true, + "version": "1.0.0", + "main": "./target_node/index.js", + "license": "SSPL-1.0 OR Elastic License 2.0" +} diff --git a/packages/core/saved-objects/core-saved-objects-base-server-internal/src/index.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/index.ts new file mode 100644 index 0000000000000..5b504f43244d6 --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/index.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { LEGACY_URL_ALIAS_TYPE, type LegacyUrlAlias } from './legacy_alias'; +export { + getProperty, + getRootProperties, + getRootPropertiesObjects, + getTypes, + type IndexMapping, + type IndexMappingMeta, + type SavedObjectsTypeMappingDefinitions, +} from './mappings'; +export { SavedObjectsSerializer } from './serialization'; +export { SavedObjectsTypeValidator } from './validation'; +export { decodeRequestVersion, decodeVersion, encodeVersion, encodeHitVersion } from './version'; +export { + savedObjectsConfig, + savedObjectsMigrationConfig, + SavedObjectConfig, + type SavedObjectsConfigType, + type SavedObjectsMigrationConfigType, +} from './saved_objects_config'; +export { SavedObjectTypeRegistry } from './saved_objects_type_registry'; diff --git a/src/core/server/saved_objects/object_types/constants.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/legacy_alias/constants.ts similarity index 100% rename from src/core/server/saved_objects/object_types/constants.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/legacy_alias/constants.ts diff --git a/src/core/server/saved_objects/version/index.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/legacy_alias/index.ts similarity index 70% rename from src/core/server/saved_objects/version/index.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/legacy_alias/index.ts index 715073fb98e7d..f782267bd2096 100644 --- a/src/core/server/saved_objects/version/index.ts +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/legacy_alias/index.ts @@ -6,7 +6,5 @@ * Side Public License, v 1. */ -export * from './encode_version'; -export * from './encode_hit_version'; -export * from './decode_version'; -export * from './decode_request_version'; +export type { LegacyUrlAlias } from './types'; +export { LEGACY_URL_ALIAS_TYPE } from './constants'; diff --git a/src/core/server/saved_objects/object_types/types.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/legacy_alias/types.ts similarity index 100% rename from src/core/server/saved_objects/object_types/types.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/legacy_alias/types.ts diff --git a/src/core/server/saved_objects/mappings/index.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/index.ts similarity index 100% rename from src/core/server/saved_objects/mappings/index.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/index.ts diff --git a/src/core/server/saved_objects/mappings/lib/get_property.test.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_property.test.ts similarity index 100% rename from src/core/server/saved_objects/mappings/lib/get_property.test.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_property.test.ts diff --git a/src/core/server/saved_objects/mappings/lib/get_property.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_property.ts similarity index 100% rename from src/core/server/saved_objects/mappings/lib/get_property.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_property.ts diff --git a/src/core/server/saved_objects/mappings/lib/get_root_properties.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_root_properties.ts similarity index 100% rename from src/core/server/saved_objects/mappings/lib/get_root_properties.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_root_properties.ts diff --git a/src/core/server/saved_objects/mappings/lib/get_root_properties_objects.test.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_root_properties_objects.test.ts similarity index 100% rename from src/core/server/saved_objects/mappings/lib/get_root_properties_objects.test.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_root_properties_objects.test.ts diff --git a/src/core/server/saved_objects/mappings/lib/get_root_properties_objects.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_root_properties_objects.ts similarity index 100% rename from src/core/server/saved_objects/mappings/lib/get_root_properties_objects.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_root_properties_objects.ts diff --git a/src/core/server/saved_objects/mappings/lib/get_types.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_types.ts similarity index 100% rename from src/core/server/saved_objects/mappings/lib/get_types.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/get_types.ts diff --git a/src/core/server/saved_objects/mappings/lib/index.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/index.ts similarity index 100% rename from src/core/server/saved_objects/mappings/lib/index.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/lib/index.ts diff --git a/src/core/server/saved_objects/mappings/types.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/types.ts similarity index 100% rename from src/core/server/saved_objects/mappings/types.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/mappings/types.ts diff --git a/src/core/server/saved_objects/saved_objects_config.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_config.ts similarity index 100% rename from src/core/server/saved_objects/saved_objects_config.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_config.ts diff --git a/src/core/server/saved_objects/saved_objects_type_registry.test.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_type_registry.test.ts similarity index 100% rename from src/core/server/saved_objects/saved_objects_type_registry.test.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_type_registry.test.ts diff --git a/src/core/server/saved_objects/saved_objects_type_registry.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_type_registry.ts similarity index 100% rename from src/core/server/saved_objects/saved_objects_type_registry.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/saved_objects_type_registry.ts diff --git a/src/core/server/saved_objects/serialization/index.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/serialization/index.ts similarity index 100% rename from src/core/server/saved_objects/serialization/index.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/serialization/index.ts diff --git a/src/core/server/saved_objects/serialization/serializer.test.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/serialization/serializer.test.ts similarity index 96% rename from src/core/server/saved_objects/serialization/serializer.test.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/serialization/serializer.test.ts index e0ef357c0d9be..230993bd06d29 100644 --- a/src/core/server/saved_objects/serialization/serializer.test.ts +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/serialization/serializer.test.ts @@ -7,28 +7,47 @@ */ import _ from 'lodash'; -import type { SavedObjectsRawDoc } from '@kbn/core-saved-objects-server'; +import type { SavedObjectsRawDoc, ISavedObjectTypeRegistry } from '@kbn/core-saved-objects-server'; import { SavedObjectsSerializer } from './serializer'; -import { typeRegistryMock } from '../saved_objects_type_registry.mock'; import { encodeVersion } from '../version'; -import { LEGACY_URL_ALIAS_TYPE } from '../object_types'; +import { LEGACY_URL_ALIAS_TYPE } from '../legacy_alias'; + +const createMockedTypeRegistry = ({ + isNamespaceAgnostic, + isSingleNamespace, + isMultiNamespace, +}: { + isNamespaceAgnostic: boolean; + isSingleNamespace: boolean; + isMultiNamespace: boolean; +}): ISavedObjectTypeRegistry => { + const typeRegistry: Partial = { + isNamespaceAgnostic: jest.fn().mockReturnValue(isNamespaceAgnostic), + isSingleNamespace: jest.fn().mockReturnValue(isSingleNamespace), + isMultiNamespace: jest.fn().mockReturnValue(isMultiNamespace), + }; + return typeRegistry as ISavedObjectTypeRegistry; +}; -let typeRegistry = typeRegistryMock.create(); -typeRegistry.isNamespaceAgnostic.mockReturnValue(true); -typeRegistry.isSingleNamespace.mockReturnValue(false); -typeRegistry.isMultiNamespace.mockReturnValue(false); +let typeRegistry = createMockedTypeRegistry({ + isNamespaceAgnostic: true, + isSingleNamespace: false, + isMultiNamespace: false, +}); const namespaceAgnosticSerializer = new SavedObjectsSerializer(typeRegistry); -typeRegistry = typeRegistryMock.create(); -typeRegistry.isNamespaceAgnostic.mockReturnValue(false); -typeRegistry.isSingleNamespace.mockReturnValue(true); -typeRegistry.isMultiNamespace.mockReturnValue(false); +typeRegistry = typeRegistry = createMockedTypeRegistry({ + isNamespaceAgnostic: false, + isSingleNamespace: true, + isMultiNamespace: false, +}); const singleNamespaceSerializer = new SavedObjectsSerializer(typeRegistry); -typeRegistry = typeRegistryMock.create(); -typeRegistry.isNamespaceAgnostic.mockReturnValue(false); -typeRegistry.isSingleNamespace.mockReturnValue(false); -typeRegistry.isMultiNamespace.mockReturnValue(true); +typeRegistry = typeRegistry = createMockedTypeRegistry({ + isNamespaceAgnostic: false, + isSingleNamespace: false, + isMultiNamespace: true, +}); const multiNamespaceSerializer = new SavedObjectsSerializer(typeRegistry); const sampleTemplate = { diff --git a/src/core/server/saved_objects/serialization/serializer.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/serialization/serializer.ts similarity index 98% rename from src/core/server/saved_objects/serialization/serializer.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/serialization/serializer.ts index 2e13708ee2f9d..340926abd0bce 100644 --- a/src/core/server/saved_objects/serialization/serializer.ts +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/serialization/serializer.ts @@ -14,9 +14,9 @@ import type { SavedObjectSanitizedDoc, SavedObjectsRawDocParseOptions, } from '@kbn/core-saved-objects-server'; -import { LEGACY_URL_ALIAS_TYPE } from '../object_types'; +import { SavedObjectsUtils } from '@kbn/core-saved-objects-utils-server'; +import { LEGACY_URL_ALIAS_TYPE } from '../legacy_alias'; import { decodeVersion, encodeVersion } from '../version'; -import { SavedObjectsUtils } from '../service'; /** * Core internal implementation of {@link ISavedObjectsSerializer} diff --git a/src/core/server/saved_objects/validation/index.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/validation/index.ts similarity index 100% rename from src/core/server/saved_objects/validation/index.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/validation/index.ts diff --git a/src/core/server/saved_objects/validation/schema.test.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/validation/schema.test.ts similarity index 100% rename from src/core/server/saved_objects/validation/schema.test.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/validation/schema.test.ts diff --git a/src/core/server/saved_objects/validation/schema.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/validation/schema.ts similarity index 97% rename from src/core/server/saved_objects/validation/schema.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/validation/schema.ts index 8e90c4aef9c70..221f21b5aa992 100644 --- a/src/core/server/saved_objects/validation/schema.ts +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/validation/schema.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { schema, Type } from '@kbn/config-schema'; +import { schema, type Type } from '@kbn/config-schema'; import type { SavedObjectsValidationSpec, SavedObjectSanitizedDoc, diff --git a/src/core/server/saved_objects/validation/validator.test.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/validation/validator.test.ts similarity index 95% rename from src/core/server/saved_objects/validation/validator.test.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/validation/validator.test.ts index b059070fdf75f..96bc93be54c1a 100644 --- a/src/core/server/saved_objects/validation/validator.test.ts +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/validation/validator.test.ts @@ -7,12 +7,12 @@ */ import { schema } from '@kbn/config-schema'; +import { loggerMock, type MockedLogger } from '@kbn/logging-mocks'; import type { SavedObjectSanitizedDoc, SavedObjectsValidationMap, } from '@kbn/core-saved-objects-server'; -import { SavedObjectsTypeValidator } from '.'; -import { loggerMock, MockedLogger } from '@kbn/logging-mocks'; +import { SavedObjectsTypeValidator } from './validator'; describe('Saved Objects type validator', () => { let validator: SavedObjectsTypeValidator; diff --git a/src/core/server/saved_objects/validation/validator.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/validation/validator.ts similarity index 100% rename from src/core/server/saved_objects/validation/validator.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/validation/validator.ts diff --git a/src/core/server/saved_objects/version/base64.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/base64.ts similarity index 100% rename from src/core/server/saved_objects/version/base64.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/base64.ts diff --git a/src/core/server/saved_objects/version/decode_request_version.test.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/decode_request_version.test.ts similarity index 100% rename from src/core/server/saved_objects/version/decode_request_version.test.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/decode_request_version.test.ts diff --git a/src/core/server/saved_objects/version/decode_request_version.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/decode_request_version.ts similarity index 100% rename from src/core/server/saved_objects/version/decode_request_version.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/decode_request_version.ts diff --git a/src/core/server/saved_objects/version/decode_version.test.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/decode_version.test.ts similarity index 100% rename from src/core/server/saved_objects/version/decode_version.test.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/decode_version.test.ts diff --git a/src/core/server/saved_objects/version/decode_version.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/decode_version.ts similarity index 93% rename from src/core/server/saved_objects/version/decode_version.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/decode_version.ts index 4166e7eef06c7..dd4bdcdc8186f 100644 --- a/src/core/server/saved_objects/version/decode_version.ts +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/decode_version.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { SavedObjectsErrorHelpers } from '../service/lib/errors'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import { decodeBase64 } from './base64'; /** diff --git a/src/core/server/saved_objects/version/encode_hit_version.test.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/encode_hit_version.test.ts similarity index 100% rename from src/core/server/saved_objects/version/encode_hit_version.test.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/encode_hit_version.test.ts diff --git a/src/core/server/saved_objects/version/encode_hit_version.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/encode_hit_version.ts similarity index 100% rename from src/core/server/saved_objects/version/encode_hit_version.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/encode_hit_version.ts diff --git a/src/core/server/saved_objects/version/encode_version.test.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/encode_version.test.ts similarity index 100% rename from src/core/server/saved_objects/version/encode_version.test.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/encode_version.test.ts diff --git a/src/core/server/saved_objects/version/encode_version.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/encode_version.ts similarity index 100% rename from src/core/server/saved_objects/version/encode_version.ts rename to packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/encode_version.ts diff --git a/packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/index.ts b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/index.ts new file mode 100644 index 0000000000000..2fb31940d4408 --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/src/version/index.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { encodeVersion } from './encode_version'; +export { encodeHitVersion } from './encode_hit_version'; +export { decodeVersion } from './decode_version'; +export { decodeRequestVersion } from './decode_request_version'; diff --git a/packages/core/saved-objects/core-saved-objects-base-server-internal/tsconfig.json b/packages/core/saved-objects/core-saved-objects-base-server-internal/tsconfig.json new file mode 100644 index 0000000000000..39d3c7097814a --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-internal/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "../../../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "rootDir": "src", + "stripInternal": false, + "types": [ + "jest", + "node" + ] + }, + "include": [ + "src/**/*" + ] +} diff --git a/packages/core/saved-objects/core-saved-objects-base-server-mocks/BUILD.bazel b/packages/core/saved-objects/core-saved-objects-base-server-mocks/BUILD.bazel new file mode 100644 index 0000000000000..9f3538c20a752 --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-mocks/BUILD.bazel @@ -0,0 +1,100 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") + +PKG_DIRNAME = "core-saved-objects-base-server-mocks" +PKG_REQUIRE_NAME = "@kbn/core-saved-objects-base-server-mocks" + +SOURCE_FILES = glob( + [ + "src/**/*.ts", + ], + exclude = [ + "**/*.test.*", + "**/*.stories.*", + ], +) + +SRCS = SOURCE_FILES + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "package.json", +] + +RUNTIME_DEPS = [ +] + +TYPES_DEPS = [ + "@npm//@types/node", + "@npm//@types/jest", + "//packages/core/saved-objects/core-saved-objects-server:npm_module_types", + "//packages/core/saved-objects/core-saved-objects-base-server-internal:npm_module_types", +] + +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), + root_input_dir = "src", +) + +ts_config( + name = "tsconfig", + src = "tsconfig.json", + deps = [ + "//:tsconfig.base.json", + "//:tsconfig.bazel.json", + ], +) + +ts_project( + name = "tsc_types", + args = ['--pretty'], + srcs = SRCS, + deps = TYPES_DEPS, + declaration = True, + declaration_map = True, + emit_declaration_only = True, + out_dir = "target_types", + root_dir = "src", + tsconfig = ":tsconfig", +) + +js_library( + name = PKG_DIRNAME, + srcs = NPM_MODULE_EXTRA_FILES, + deps = RUNTIME_DEPS + [":target_node"], + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [":" + PKG_DIRNAME], +) + +filegroup( + name = "build", + srcs = [":npm_module"], + visibility = ["//visibility:public"], +) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [":npm_module_types"], + visibility = ["//visibility:public"], +) diff --git a/packages/core/saved-objects/core-saved-objects-base-server-mocks/README.md b/packages/core/saved-objects/core-saved-objects-base-server-mocks/README.md new file mode 100644 index 0000000000000..5da5264ce9eed --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-mocks/README.md @@ -0,0 +1,5 @@ +# @kbn/core-saved-objects-base-server-mocks + +This package contains the mocks for the base server-side savedObjects sub-domain: +- `SavedObjectTypeRegistry` mock +- `SavedObjectsSerializer` mock diff --git a/packages/core/saved-objects/core-saved-objects-base-server-mocks/jest.config.js b/packages/core/saved-objects/core-saved-objects-base-server-mocks/jest.config.js new file mode 100644 index 0000000000000..fee774e787693 --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-mocks/jest.config.js @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +module.exports = { + preset: '@kbn/test/jest_node', + rootDir: '../../../..', + roots: ['/packages/core/saved-objects/core-saved-objects-base-server-mocks'], +}; diff --git a/packages/core/saved-objects/core-saved-objects-base-server-mocks/package.json b/packages/core/saved-objects/core-saved-objects-base-server-mocks/package.json new file mode 100644 index 0000000000000..e119e704c7ace --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-mocks/package.json @@ -0,0 +1,7 @@ +{ + "name": "@kbn/core-saved-objects-base-server-mocks", + "private": true, + "version": "1.0.0", + "main": "./target_node/index.js", + "license": "SSPL-1.0 OR Elastic License 2.0" +} diff --git a/packages/core/saved-objects/core-saved-objects-base-server-mocks/src/index.ts b/packages/core/saved-objects/core-saved-objects-base-server-mocks/src/index.ts new file mode 100644 index 0000000000000..62657cf81ea61 --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-mocks/src/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { typeRegistryMock } from './saved_objects_type_registry.mock'; +export { serializerMock } from './serializer.mock'; diff --git a/src/core/server/saved_objects/saved_objects_type_registry.mock.ts b/packages/core/saved-objects/core-saved-objects-base-server-mocks/src/saved_objects_type_registry.mock.ts similarity index 94% rename from src/core/server/saved_objects/saved_objects_type_registry.mock.ts rename to packages/core/saved-objects/core-saved-objects-base-server-mocks/src/saved_objects_type_registry.mock.ts index 70d05a0f7b0ab..8f792f177b5fc 100644 --- a/src/core/server/saved_objects/saved_objects_type_registry.mock.ts +++ b/packages/core/saved-objects/core-saved-objects-base-server-mocks/src/saved_objects_type_registry.mock.ts @@ -7,7 +7,7 @@ */ import type { ISavedObjectTypeRegistry } from '@kbn/core-saved-objects-server'; -import type { SavedObjectTypeRegistry } from './saved_objects_type_registry'; +import type { SavedObjectTypeRegistry } from '@kbn/core-saved-objects-base-server-internal'; const createRegistryMock = (): jest.Mocked< ISavedObjectTypeRegistry & Pick diff --git a/packages/core/saved-objects/core-saved-objects-base-server-mocks/src/serializer.mock.ts b/packages/core/saved-objects/core-saved-objects-base-server-mocks/src/serializer.mock.ts new file mode 100644 index 0000000000000..6bdac2e20c1f9 --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-mocks/src/serializer.mock.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { ISavedObjectsSerializer } from '@kbn/core-saved-objects-server'; + +const createSerializerMock = () => { + const mock: jest.Mocked = { + isRawSavedObject: jest.fn(), + rawToSavedObject: jest.fn(), + savedObjectToRaw: jest.fn(), + generateRawId: jest.fn(), + generateRawLegacyUrlAliasId: jest.fn(), + }; + return mock; +}; + +export const serializerMock = { + create: createSerializerMock, +}; diff --git a/packages/core/saved-objects/core-saved-objects-base-server-mocks/tsconfig.json b/packages/core/saved-objects/core-saved-objects-base-server-mocks/tsconfig.json new file mode 100644 index 0000000000000..39d3c7097814a --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-base-server-mocks/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "../../../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "rootDir": "src", + "stripInternal": false, + "types": [ + "jest", + "node" + ] + }, + "include": [ + "src/**/*" + ] +} diff --git a/packages/core/saved-objects/core-saved-objects-utils-server/BUILD.bazel b/packages/core/saved-objects/core-saved-objects-utils-server/BUILD.bazel new file mode 100644 index 0000000000000..71a61799ee46a --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-utils-server/BUILD.bazel @@ -0,0 +1,106 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") + +PKG_DIRNAME = "core-saved-objects-utils-server" +PKG_REQUIRE_NAME = "@kbn/core-saved-objects-utils-server" + +SOURCE_FILES = glob( + [ + "src/**/*.ts", + ], + exclude = [ + "**/*.test.*", + "**/*.stories.*", + ], +) + +SRCS = SOURCE_FILES + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "package.json", +] + +RUNTIME_DEPS = [ + "@npm//lodash", + "@npm//uuid", + "@npm//@hapi/boom", +] + + +TYPES_DEPS = [ + "@npm//@types/node", + "@npm//@types/jest", + "@npm//@types/lodash", + "@npm//@types/uuid", + "@npm//@hapi/boom", + "//packages/core/saved-objects/core-saved-objects-server:npm_module_types", +] + +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), + root_input_dir = "src", +) + +ts_config( + name = "tsconfig", + src = "tsconfig.json", + deps = [ + "//:tsconfig.base.json", + "//:tsconfig.bazel.json", + ], +) + +ts_project( + name = "tsc_types", + args = ['--pretty'], + srcs = SRCS, + deps = TYPES_DEPS, + declaration = True, + declaration_map = True, + emit_declaration_only = True, + out_dir = "target_types", + root_dir = "src", + tsconfig = ":tsconfig", +) + +js_library( + name = PKG_DIRNAME, + srcs = NPM_MODULE_EXTRA_FILES, + deps = RUNTIME_DEPS + [":target_node"], + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [":" + PKG_DIRNAME], +) + +filegroup( + name = "build", + srcs = [":npm_module"], + visibility = ["//visibility:public"], +) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [":npm_module_types"], + visibility = ["//visibility:public"], +) diff --git a/packages/core/saved-objects/core-saved-objects-utils-server/README.md b/packages/core/saved-objects/core-saved-objects-utils-server/README.md new file mode 100644 index 0000000000000..ecbfa469575ae --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-utils-server/README.md @@ -0,0 +1,5 @@ +# @kbn/core-saved-objects-utils-server + +This package contains public utilities for Core's server-side `savedObjects` domain. + + diff --git a/packages/core/saved-objects/core-saved-objects-utils-server/jest.config.js b/packages/core/saved-objects/core-saved-objects-utils-server/jest.config.js new file mode 100644 index 0000000000000..5458bf05b6767 --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-utils-server/jest.config.js @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +module.exports = { + preset: '@kbn/test/jest_node', + rootDir: '../../../..', + roots: ['/packages/core/saved-objects/core-saved-objects-utils-server'], +}; diff --git a/packages/core/saved-objects/core-saved-objects-utils-server/package.json b/packages/core/saved-objects/core-saved-objects-utils-server/package.json new file mode 100644 index 0000000000000..13220da373261 --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-utils-server/package.json @@ -0,0 +1,7 @@ +{ + "name": "@kbn/core-saved-objects-utils-server", + "private": true, + "version": "1.0.0", + "main": "./target_node/index.js", + "license": "SSPL-1.0 OR Elastic License 2.0" +} diff --git a/packages/core/saved-objects/core-saved-objects-utils-server/src/index.ts b/packages/core/saved-objects/core-saved-objects-utils-server/src/index.ts new file mode 100644 index 0000000000000..3704cebf08398 --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-utils-server/src/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { mergeSavedObjectMigrationMaps } from './merge_migration_maps'; +export { SavedObjectsErrorHelpers, type DecoratedError } from './saved_objects_error_helpers'; +export { + SavedObjectsUtils, + ALL_NAMESPACES_STRING, + DEFAULT_NAMESPACE_STRING, + FIND_DEFAULT_PAGE, + FIND_DEFAULT_PER_PAGE, +} from './saved_objects_utils'; diff --git a/src/core/server/saved_objects/migrations/utils.test.ts b/packages/core/saved-objects/core-saved-objects-utils-server/src/merge_migration_maps.test.ts similarity index 96% rename from src/core/server/saved_objects/migrations/utils.test.ts rename to packages/core/saved-objects/core-saved-objects-utils-server/src/merge_migration_maps.test.ts index e3378c3fb9e78..28b3ebd3735b4 100644 --- a/src/core/server/saved_objects/migrations/utils.test.ts +++ b/packages/core/saved-objects/core-saved-objects-utils-server/src/merge_migration_maps.test.ts @@ -11,7 +11,7 @@ import type { SavedObjectMigrationMap, SavedObjectUnsanitizedDoc, } from '@kbn/core-saved-objects-server'; -import { mergeSavedObjectMigrationMaps } from './utils'; +import { mergeSavedObjectMigrationMaps } from './merge_migration_maps'; describe('mergeSavedObjectMigrationMaps', () => { const obj1: SavedObjectMigrationMap = { diff --git a/src/core/server/saved_objects/migrations/utils.ts b/packages/core/saved-objects/core-saved-objects-utils-server/src/merge_migration_maps.ts similarity index 96% rename from src/core/server/saved_objects/migrations/utils.ts rename to packages/core/saved-objects/core-saved-objects-utils-server/src/merge_migration_maps.ts index 108317fc6698b..e5f2f1d74a7cf 100644 --- a/src/core/server/saved_objects/migrations/utils.ts +++ b/packages/core/saved-objects/core-saved-objects-utils-server/src/merge_migration_maps.ts @@ -7,12 +7,12 @@ */ import { mergeWith } from 'lodash'; -import { +import type { SavedObjectMigrationContext, SavedObjectMigrationFn, SavedObjectMigrationMap, SavedObjectUnsanitizedDoc, -} from '../..'; +} from '@kbn/core-saved-objects-server'; /** * Merges two saved object migration maps. diff --git a/src/core/server/saved_objects/service/lib/errors.test.ts b/packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.test.ts similarity index 99% rename from src/core/server/saved_objects/service/lib/errors.test.ts rename to packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.test.ts index 3bea693429254..6f312a09a56e9 100644 --- a/src/core/server/saved_objects/service/lib/errors.test.ts +++ b/packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.test.ts @@ -7,8 +7,7 @@ */ import Boom from '@hapi/boom'; - -import { SavedObjectsErrorHelpers } from './errors'; +import { SavedObjectsErrorHelpers } from './saved_objects_error_helpers'; describe('savedObjectsClient/errorTypes', () => { describe('BadRequest error', () => { diff --git a/src/core/server/saved_objects/service/lib/errors.ts b/packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts similarity index 100% rename from src/core/server/saved_objects/service/lib/errors.ts rename to packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_error_helpers.ts diff --git a/src/core/server/saved_objects/service/lib/utils.test.mock.ts b/packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.test.mock.ts similarity index 100% rename from src/core/server/saved_objects/service/lib/utils.test.mock.ts rename to packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.test.mock.ts diff --git a/src/core/server/saved_objects/service/lib/utils.test.ts b/packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.test.ts similarity index 94% rename from src/core/server/saved_objects/service/lib/utils.test.ts rename to packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.test.ts index 8c836afd087d3..717b52ef248ca 100644 --- a/src/core/server/saved_objects/service/lib/utils.test.ts +++ b/packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.test.ts @@ -6,10 +6,10 @@ * Side Public License, v 1. */ -import { mockUuidv1, mockUuidv5 } from './utils.test.mock'; +import { mockUuidv1, mockUuidv5 } from './saved_objects_utils.test.mock'; -import { SavedObjectsFindOptions } from '@kbn/core-saved-objects-api-server'; -import { SavedObjectsUtils } from './utils'; +import type { SavedObjectsFindOptions } from '@kbn/core-saved-objects-api-server'; +import { SavedObjectsUtils } from './saved_objects_utils'; describe('SavedObjectsUtils', () => { const { diff --git a/src/core/server/saved_objects/service/lib/utils.ts b/packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.ts similarity index 100% rename from src/core/server/saved_objects/service/lib/utils.ts rename to packages/core/saved-objects/core-saved-objects-utils-server/src/saved_objects_utils.ts diff --git a/packages/core/saved-objects/core-saved-objects-utils-server/tsconfig.json b/packages/core/saved-objects/core-saved-objects-utils-server/tsconfig.json new file mode 100644 index 0000000000000..39d3c7097814a --- /dev/null +++ b/packages/core/saved-objects/core-saved-objects-utils-server/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "../../../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "rootDir": "src", + "stripInternal": false, + "types": [ + "jest", + "node" + ] + }, + "include": [ + "src/**/*" + ] +} diff --git a/src/core/server/core_usage_data/core_usage_data_service.test.ts b/src/core/server/core_usage_data/core_usage_data_service.test.ts index c45b3fdb0a125..5ac2863745ee7 100644 --- a/src/core/server/core_usage_data/core_usage_data_service.test.ts +++ b/src/core/server/core_usage_data/core_usage_data_service.test.ts @@ -18,14 +18,14 @@ import { mockCoreContext } from '@kbn/core-base-server-mocks'; import { config as RawLoggingConfig } from '@kbn/core-logging-server-internal'; import { config as RawElasticsearchConfig } from '@kbn/core-elasticsearch-server-internal'; import { config as RawHttpConfig } from '@kbn/core-http-server-internal'; -import { savedObjectsConfig as RawSavedObjectsConfig } from '../saved_objects/saved_objects_config'; +import { savedObjectsConfig as RawSavedObjectsConfig } from '@kbn/core-saved-objects-base-server-internal'; import { httpServiceMock } from '@kbn/core-http-server-mocks'; import { metricsServiceMock } from '@kbn/core-metrics-server-mocks'; import { savedObjectsServiceMock } from '../saved_objects/saved_objects_service.mock'; import { CoreUsageDataService } from './core_usage_data_service'; import { elasticsearchServiceMock } from '@kbn/core-elasticsearch-server-mocks'; -import { typeRegistryMock } from '../saved_objects/saved_objects_type_registry.mock'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { CORE_USAGE_STATS_TYPE } from './constants'; import { CoreUsageStatsClient } from './core_usage_stats_client'; diff --git a/src/core/server/core_usage_data/core_usage_data_service.ts b/src/core/server/core_usage_data/core_usage_data_service.ts index f1e51a7e5f5aa..c5f2335e333e4 100644 --- a/src/core/server/core_usage_data/core_usage_data_service.ts +++ b/src/core/server/core_usage_data/core_usage_data_service.ts @@ -23,9 +23,12 @@ import type { HttpConfigType, InternalHttpServiceSetup } from '@kbn/core-http-se import type { ElasticsearchServiceStart } from '@kbn/core-elasticsearch-server'; import type { ElasticsearchConfigType } from '@kbn/core-elasticsearch-server-internal'; import type { MetricsServiceSetup, OpsMetrics } from '@kbn/core-metrics-server'; -import { SavedObjectsServiceStart, SavedObjectTypeRegistry } from '..'; +import { + LEGACY_URL_ALIAS_TYPE, + type SavedObjectsConfigType, +} from '@kbn/core-saved-objects-base-server-internal'; -import { SavedObjectsConfigType } from '../saved_objects/saved_objects_config'; +import { SavedObjectsServiceStart, SavedObjectTypeRegistry } from '..'; import type { CoreServicesUsageData, CoreUsageData, @@ -36,7 +39,6 @@ import type { } from './types'; import { isConfigured } from './is_configured'; import { coreUsageStatsType } from './core_usage_stats'; -import { LEGACY_URL_ALIAS_TYPE } from '../saved_objects/object_types'; import { CORE_USAGE_STATS_TYPE } from './constants'; import { CoreUsageStatsClient } from './core_usage_stats_client'; import { CoreIncrementUsageCounter } from './types'; diff --git a/src/core/server/core_usage_data/core_usage_stats_client.test.ts b/src/core/server/core_usage_data/core_usage_stats_client.test.ts index 6bcaa38bd0062..9a6984f6b5785 100644 --- a/src/core/server/core_usage_data/core_usage_stats_client.test.ts +++ b/src/core/server/core_usage_data/core_usage_stats_client.test.ts @@ -29,8 +29,8 @@ import { LEGACY_DASHBOARDS_EXPORT_STATS_PREFIX, BULK_RESOLVE_STATS_PREFIX, } from './core_usage_stats_client'; +import { DEFAULT_NAMESPACE_STRING } from '@kbn/core-saved-objects-utils-server'; import { CoreUsageStatsClient } from '.'; -import { DEFAULT_NAMESPACE_STRING } from '../saved_objects/service/lib/utils'; describe('CoreUsageStatsClient', () => { const setup = (namespace?: string) => { diff --git a/src/core/server/core_usage_data/core_usage_stats_client.ts b/src/core/server/core_usage_data/core_usage_stats_client.ts index 2dd8c77fd1876..c14776ff7ed81 100644 --- a/src/core/server/core_usage_data/core_usage_stats_client.ts +++ b/src/core/server/core_usage_data/core_usage_stats_client.ts @@ -6,9 +6,9 @@ * Side Public License, v 1. */ +import { DEFAULT_NAMESPACE_STRING } from '@kbn/core-saved-objects-utils-server'; import { CORE_USAGE_STATS_TYPE, CORE_USAGE_STATS_ID } from './constants'; import { CoreUsageStats } from './types'; -import { DEFAULT_NAMESPACE_STRING } from '../saved_objects/service/lib/utils'; import { ISavedObjectsRepository, SavedObjectsImportOptions, diff --git a/src/core/server/index.ts b/src/core/server/index.ts index 0f365366206d2..3327340c91a8c 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -388,6 +388,12 @@ export type { ISavedObjectsSerializer, SavedObjectsRequestHandlerContext, } from '@kbn/core-saved-objects-server'; +export { + SavedObjectsErrorHelpers, + SavedObjectsUtils, + mergeSavedObjectMigrationMaps, +} from '@kbn/core-saved-objects-utils-server'; +export { SavedObjectTypeRegistry } from '@kbn/core-saved-objects-base-server-internal'; export type { SavedObjectsRepository, @@ -396,14 +402,7 @@ export type { SavedObjectsImporter, SavedObjectsImportError, } from './saved_objects'; -export { - SavedObjectsClient, - SavedObjectsErrorHelpers, - SavedObjectsSerializer, - SavedObjectTypeRegistry, - SavedObjectsUtils, - mergeSavedObjectMigrationMaps, -} from './saved_objects'; +export { SavedObjectsClient } from './saved_objects'; export type { IUiSettingsClient, diff --git a/src/core/server/integration_tests/saved_objects/routes/delete_unknown_types.test.ts b/src/core/server/integration_tests/saved_objects/routes/delete_unknown_types.test.ts index 4a13921750d1f..b4a215169a376 100644 --- a/src/core/server/integration_tests/saved_objects/routes/delete_unknown_types.test.ts +++ b/src/core/server/integration_tests/saved_objects/routes/delete_unknown_types.test.ts @@ -8,8 +8,8 @@ import supertest from 'supertest'; import { elasticsearchServiceMock } from '@kbn/core-elasticsearch-server-mocks'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { registerDeleteUnknownTypesRoute } from '../../../saved_objects/routes/deprecations'; -import { typeRegistryMock } from '../../../saved_objects/saved_objects_type_registry.mock'; import { setupServer } from '../../../saved_objects/routes/test_utils'; import { SavedObjectsType } from '../../..'; import type { InternalSavedObjectsRequestHandlerContext } from '../../../saved_objects/internal_types'; diff --git a/src/core/server/integration_tests/saved_objects/routes/export.test.ts b/src/core/server/integration_tests/saved_objects/routes/export.test.ts index 358a23902d5e1..b107d1266fe3c 100644 --- a/src/core/server/integration_tests/saved_objects/routes/export.test.ts +++ b/src/core/server/integration_tests/saved_objects/routes/export.test.ts @@ -16,7 +16,7 @@ import { CoreUsageStatsClient } from '../../../core_usage_data'; import { coreUsageStatsClientMock } from '../../../core_usage_data/core_usage_stats_client.mock'; import { coreUsageDataServiceMock } from '../../../core_usage_data/core_usage_data_service.mock'; import { savedObjectsExporterMock } from '../../../saved_objects/export/saved_objects_exporter.mock'; -import { SavedObjectConfig } from '../../../saved_objects/saved_objects_config'; +import type { SavedObjectConfig } from '@kbn/core-saved-objects-base-server-internal'; import { registerExportRoute } from '../../../saved_objects/routes/export'; import { setupServer, createExportableType } from '../../../saved_objects/routes/test_utils'; import type { InternalSavedObjectsRequestHandlerContext } from '../../../saved_objects/internal_types'; diff --git a/src/core/server/integration_tests/saved_objects/routes/import.test.ts b/src/core/server/integration_tests/saved_objects/routes/import.test.ts index a9062b8d07919..ec6a483e8ae1f 100644 --- a/src/core/server/integration_tests/saved_objects/routes/import.test.ts +++ b/src/core/server/integration_tests/saved_objects/routes/import.test.ts @@ -9,14 +9,15 @@ jest.mock('uuid'); import supertest from 'supertest'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import { registerImportRoute } from '../../../saved_objects/routes/import'; import { savedObjectsClientMock } from '../../../mocks'; import { CoreUsageStatsClient } from '../../../core_usage_data'; import { coreUsageStatsClientMock } from '../../../core_usage_data/core_usage_stats_client.mock'; import { coreUsageDataServiceMock } from '../../../core_usage_data/core_usage_data_service.mock'; -import { SavedObjectConfig } from '../../../saved_objects/saved_objects_config'; +import { SavedObjectConfig } from '@kbn/core-saved-objects-base-server-internal'; import { setupServer, createExportableType } from '../../../saved_objects/routes/test_utils'; -import { SavedObjectsErrorHelpers, SavedObjectsImporter } from '../../../saved_objects'; +import { SavedObjectsImporter } from '../../../saved_objects'; import type { InternalSavedObjectsRequestHandlerContext } from '../../../saved_objects/internal_types'; type SetupServerReturn = Awaited>; diff --git a/src/core/server/integration_tests/saved_objects/routes/resolve_import_errors.test.ts b/src/core/server/integration_tests/saved_objects/routes/resolve_import_errors.test.ts index defdbc5cfc1d6..5d26fde36fae4 100644 --- a/src/core/server/integration_tests/saved_objects/routes/resolve_import_errors.test.ts +++ b/src/core/server/integration_tests/saved_objects/routes/resolve_import_errors.test.ts @@ -15,7 +15,7 @@ import { CoreUsageStatsClient } from '../../../core_usage_data'; import { coreUsageStatsClientMock } from '../../../core_usage_data/core_usage_stats_client.mock'; import { coreUsageDataServiceMock } from '../../../core_usage_data/core_usage_data_service.mock'; import { setupServer, createExportableType } from '../../../saved_objects/routes/test_utils'; -import { SavedObjectConfig } from '../../../saved_objects/saved_objects_config'; +import { SavedObjectConfig } from '@kbn/core-saved-objects-base-server-internal'; import { SavedObjectsImporter } from '../../../saved_objects/import'; import type { InternalSavedObjectsRequestHandlerContext } from '../../../saved_objects/internal_types'; diff --git a/src/core/server/mocks.ts b/src/core/server/mocks.ts index a98eaf50554f2..e2ae9a96b716d 100644 --- a/src/core/server/mocks.ts +++ b/src/core/server/mocks.ts @@ -23,6 +23,7 @@ import { httpServiceMock } from '@kbn/core-http-server-mocks'; import { elasticsearchServiceMock } from '@kbn/core-elasticsearch-server-mocks'; import { metricsServiceMock } from '@kbn/core-metrics-server-mocks'; import { capabilitiesServiceMock } from '@kbn/core-capabilities-server-mocks'; +import { typeRegistryMock as savedObjectsTypeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import type { PluginInitializerContext, CoreSetup, @@ -34,7 +35,6 @@ import type { import { httpResourcesMock } from './http_resources/http_resources_service.mock'; import { savedObjectsServiceMock } from './saved_objects/saved_objects_service.mock'; import { savedObjectsClientMock } from './saved_objects/service/saved_objects_client.mock'; -import { typeRegistryMock as savedObjectsTypeRegistryMock } from './saved_objects/saved_objects_type_registry.mock'; import { renderingMock } from './rendering/rendering_service.mock'; import { uiSettingsServiceMock } from './ui_settings/ui_settings_service.mock'; import { SharedGlobalConfig } from './plugins'; @@ -47,12 +47,12 @@ export { configServiceMock, configDeprecationsMock } from '@kbn/config-mocks'; export { loggingSystemMock } from '@kbn/core-logging-server-mocks'; export { httpServerMock, sessionStorageMock, httpServiceMock } from '@kbn/core-http-server-mocks'; export { elasticsearchServiceMock } from '@kbn/core-elasticsearch-server-mocks'; +export { typeRegistryMock as savedObjectsTypeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; export { httpResourcesMock } from './http_resources/http_resources_service.mock'; export { savedObjectsRepositoryMock } from './saved_objects/service/lib/repository.mock'; export { savedObjectsServiceMock } from './saved_objects/saved_objects_service.mock'; export { savedObjectsClientMock } from './saved_objects/service/saved_objects_client.mock'; export { migrationMocks } from './saved_objects/migrations/mocks'; -export { typeRegistryMock as savedObjectsTypeRegistryMock } from './saved_objects/saved_objects_type_registry.mock'; export { uiSettingsServiceMock } from './ui_settings/ui_settings_service.mock'; export { metricsServiceMock } from '@kbn/core-metrics-server-mocks'; export { renderingMock } from './rendering/rendering_service.mock'; diff --git a/src/core/server/plugins/legacy_config.ts b/src/core/server/plugins/legacy_config.ts index 4bee00d615748..de86345c5b7ba 100644 --- a/src/core/server/plugins/legacy_config.ts +++ b/src/core/server/plugins/legacy_config.ts @@ -16,8 +16,11 @@ import { ElasticsearchConfigType, config as elasticsearchConfig, } from '@kbn/core-elasticsearch-server-internal'; +import { + type SavedObjectsConfigType, + savedObjectsConfig, +} from '@kbn/core-saved-objects-base-server-internal'; import { SharedGlobalConfig, SharedGlobalConfigKeys } from './types'; -import { SavedObjectsConfigType, savedObjectsConfig } from '../saved_objects/saved_objects_config'; const createGlobalConfig = ({ elasticsearch, diff --git a/src/core/server/plugins/types.ts b/src/core/server/plugins/types.ts index d41be740018a7..f8b20b66f5069 100644 --- a/src/core/server/plugins/types.ts +++ b/src/core/server/plugins/types.ts @@ -20,8 +20,7 @@ import type { import type { PluginName, PluginOpaqueId, PluginType } from '@kbn/core-base-common'; import type { NodeInfo } from '@kbn/core-node-server'; import type { ElasticsearchConfigType } from '@kbn/core-elasticsearch-server-internal'; - -import { SavedObjectsConfigType } from '../saved_objects/saved_objects_config'; +import type { SavedObjectsConfigType } from '@kbn/core-saved-objects-base-server-internal'; import { CorePreboot, CoreSetup, CoreStart } from '..'; type Maybe = T | undefined; diff --git a/src/core/server/saved_objects/deprecations/deprecation_factory.ts b/src/core/server/saved_objects/deprecations/deprecation_factory.ts index dea29cb7690ec..d330577151a52 100644 --- a/src/core/server/saved_objects/deprecations/deprecation_factory.ts +++ b/src/core/server/saved_objects/deprecations/deprecation_factory.ts @@ -7,8 +7,8 @@ */ import type { ISavedObjectTypeRegistry } from '@kbn/core-saved-objects-server'; +import type { SavedObjectConfig } from '@kbn/core-saved-objects-base-server-internal'; import type { RegisterDeprecationsConfig } from '../../deprecations'; -import type { SavedObjectConfig } from '../saved_objects_config'; import { getUnknownTypesDeprecations } from './unknown_object_types'; interface GetDeprecationProviderOptions { diff --git a/src/core/server/saved_objects/deprecations/unknown_object_types.test.ts b/src/core/server/saved_objects/deprecations/unknown_object_types.test.ts index 51f228f46438b..7e02f3343050d 100644 --- a/src/core/server/saved_objects/deprecations/unknown_object_types.test.ts +++ b/src/core/server/saved_objects/deprecations/unknown_object_types.test.ts @@ -9,7 +9,7 @@ import { getIndexForTypeMock } from './unknown_object_types.test.mocks'; import { deleteUnknownTypeObjects, getUnknownTypesDeprecations } from './unknown_object_types'; -import { typeRegistryMock } from '../saved_objects_type_registry.mock'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; import { SavedObjectsType } from '../..'; import { createAggregateTypesSearchResponse } from '../migrations/actions/check_for_unknown_docs.mocks'; diff --git a/src/core/server/saved_objects/export/collect_exported_objects.test.ts b/src/core/server/saved_objects/export/collect_exported_objects.test.ts index 8aedffdd3745b..480a80e23cc97 100644 --- a/src/core/server/saved_objects/export/collect_exported_objects.test.ts +++ b/src/core/server/saved_objects/export/collect_exported_objects.test.ts @@ -15,7 +15,7 @@ import type { import { applyExportTransformsMock } from './collect_exported_objects.test.mocks'; import { savedObjectsClientMock } from '../../mocks'; import { loggerMock } from '@kbn/logging-mocks'; -import { SavedObjectTypeRegistry } from '../saved_objects_type_registry'; +import { SavedObjectTypeRegistry } from '@kbn/core-saved-objects-base-server-internal'; import { collectExportedObjects, ExclusionReason } from './collect_exported_objects'; const createObject = (parts: Partial): SavedObject => ({ diff --git a/src/core/server/saved_objects/export/saved_objects_exporter.test.ts b/src/core/server/saved_objects/export/saved_objects_exporter.test.ts index 8b4604087141c..55ee7642388ba 100644 --- a/src/core/server/saved_objects/export/saved_objects_exporter.test.ts +++ b/src/core/server/saved_objects/export/saved_objects_exporter.test.ts @@ -8,9 +8,9 @@ import { httpServerMock } from '@kbn/core-http-server-mocks'; import type { SavedObject } from '@kbn/core-saved-objects-common'; +import { SavedObjectTypeRegistry } from '@kbn/core-saved-objects-base-server-internal'; import { SavedObjectsExporter } from './saved_objects_exporter'; import { savedObjectsClientMock } from '../service/saved_objects_client.mock'; -import { SavedObjectTypeRegistry } from '../saved_objects_type_registry'; import { loggerMock, MockedLogger } from '@kbn/logging-mocks'; import { Readable } from 'stream'; import { createPromiseFromStreams, createConcatStream } from '@kbn/utils'; diff --git a/src/core/server/saved_objects/import/import_saved_objects.test.ts b/src/core/server/saved_objects/import/import_saved_objects.test.ts index 71990a8438ef3..9a086537c4761 100644 --- a/src/core/server/saved_objects/import/import_saved_objects.test.ts +++ b/src/core/server/saved_objects/import/import_saved_objects.test.ts @@ -30,8 +30,8 @@ import type { ISavedObjectTypeRegistry, SavedObjectsImportHook, } from '@kbn/core-saved-objects-server'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { savedObjectsClientMock } from '../../mocks'; -import { typeRegistryMock } from '../saved_objects_type_registry.mock'; import { importSavedObjectsFromStream, ImportSavedObjectsOptions } from './import_saved_objects'; import type { ImportStateMap } from './lib'; diff --git a/src/core/server/saved_objects/import/lib/check_conflicts.test.ts b/src/core/server/saved_objects/import/lib/check_conflicts.test.ts index 3dcbeacae1a2d..35be4e245086c 100644 --- a/src/core/server/saved_objects/import/lib/check_conflicts.test.ts +++ b/src/core/server/saved_objects/import/lib/check_conflicts.test.ts @@ -13,7 +13,7 @@ import type { SavedObjectsImportRetry, } from '@kbn/core-saved-objects-common'; import type { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; -import { SavedObjectsErrorHelpers } from '../../service'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import { checkConflicts } from './check_conflicts'; jest.mock('uuid', () => ({ diff --git a/src/core/server/saved_objects/import/lib/check_origin_conflicts.test.ts b/src/core/server/saved_objects/import/lib/check_origin_conflicts.test.ts index ed80c7cdf0751..756214e2ddc03 100644 --- a/src/core/server/saved_objects/import/lib/check_origin_conflicts.test.ts +++ b/src/core/server/saved_objects/import/lib/check_origin_conflicts.test.ts @@ -16,9 +16,9 @@ import type { } from '@kbn/core-saved-objects-common'; import type { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; import type { ISavedObjectTypeRegistry } from '@kbn/core-saved-objects-server'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { checkOriginConflicts } from './check_origin_conflicts'; import { savedObjectsClientMock } from '../../../mocks'; -import { typeRegistryMock } from '../../saved_objects_type_registry.mock'; import type { ImportStateMap } from './types'; jest.mock('uuid', () => ({ diff --git a/src/core/server/saved_objects/import/lib/check_reference_origins.test.ts b/src/core/server/saved_objects/import/lib/check_reference_origins.test.ts index cff3a4d5540a0..fce677ec6ea46 100644 --- a/src/core/server/saved_objects/import/lib/check_reference_origins.test.ts +++ b/src/core/server/saved_objects/import/lib/check_reference_origins.test.ts @@ -15,7 +15,7 @@ import type { import type { ISavedObjectTypeRegistry } from '@kbn/core-saved-objects-server'; import { checkReferenceOrigins, CheckReferenceOriginsParams } from './check_reference_origins'; import { savedObjectsClientMock } from '../../../mocks'; -import { typeRegistryMock } from '../../saved_objects_type_registry.mock'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import type { ImportStateMap } from './types'; const MULTI_NS_TYPE = 'multi'; diff --git a/src/core/server/saved_objects/import/lib/create_saved_objects.test.ts b/src/core/server/saved_objects/import/lib/create_saved_objects.test.ts index a29765849c364..363d2bee5899e 100644 --- a/src/core/server/saved_objects/import/lib/create_saved_objects.test.ts +++ b/src/core/server/saved_objects/import/lib/create_saved_objects.test.ts @@ -9,8 +9,8 @@ import { savedObjectsClientMock } from '../../../mocks'; import type { SavedObject, SavedObjectsImportFailure } from '@kbn/core-saved-objects-common'; import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import { createSavedObjects } from './create_saved_objects'; -import { SavedObjectsErrorHelpers } from '../../service'; import { extractErrors } from './extract_errors'; type CreateSavedObjectsParams = Parameters[0]; diff --git a/src/core/server/saved_objects/import/lib/extract_errors.test.ts b/src/core/server/saved_objects/import/lib/extract_errors.test.ts index 20a8d40b62a70..c4d3d0e4c2722 100644 --- a/src/core/server/saved_objects/import/lib/extract_errors.test.ts +++ b/src/core/server/saved_objects/import/lib/extract_errors.test.ts @@ -8,8 +8,8 @@ import type { SavedObject } from '@kbn/core-saved-objects-common'; import type { CreatedObject } from '@kbn/core-saved-objects-server'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import { extractErrors } from './extract_errors'; -import { SavedObjectsErrorHelpers } from '../../service'; describe('extractErrors()', () => { test('returns empty array when no errors exist', () => { diff --git a/src/core/server/saved_objects/import/lib/validate_references.test.ts b/src/core/server/saved_objects/import/lib/validate_references.test.ts index 2e6f1a5e0a9a2..2a8095ef78ce8 100644 --- a/src/core/server/saved_objects/import/lib/validate_references.test.ts +++ b/src/core/server/saved_objects/import/lib/validate_references.test.ts @@ -6,10 +6,10 @@ * Side Public License, v 1. */ +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import type { ValidateReferencesParams } from './validate_references'; import { validateReferences } from './validate_references'; import { savedObjectsClientMock } from '../../../mocks'; -import { SavedObjectsErrorHelpers } from '../../service'; function setup({ objects = [], diff --git a/src/core/server/saved_objects/import/resolve_import_errors.test.ts b/src/core/server/saved_objects/import/resolve_import_errors.test.ts index bc297182b281d..288e58aabb4c2 100644 --- a/src/core/server/saved_objects/import/resolve_import_errors.test.ts +++ b/src/core/server/saved_objects/import/resolve_import_errors.test.ts @@ -36,8 +36,8 @@ import type { ISavedObjectTypeRegistry, SavedObjectsImportHook, } from '@kbn/core-saved-objects-server'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { savedObjectsClientMock } from '../../mocks'; -import { typeRegistryMock } from '../saved_objects_type_registry.mock'; import { resolveSavedObjectsImportErrors, ResolveSavedObjectsImportErrorsOptions, diff --git a/src/core/server/saved_objects/index.ts b/src/core/server/saved_objects/index.ts index 4a7a14b45b665..4ccc4f1bcdb30 100644 --- a/src/core/server/saved_objects/index.ts +++ b/src/core/server/saved_objects/index.ts @@ -14,8 +14,6 @@ export type { SavedObjectsImportError } from './import'; export type { SavedObjectsExporter, SavedObjectsExportError } from './export'; -export { SavedObjectsSerializer } from './serialization'; - export { SavedObjectsService } from './saved_objects_service'; export type { @@ -23,10 +21,4 @@ export type { InternalSavedObjectsServiceSetup, } from './saved_objects_service'; -export type { SavedObjectsTypeMappingDefinitions } from './mappings'; - -export { mergeSavedObjectMigrationMaps } from './migrations'; - -export { savedObjectsConfig, savedObjectsMigrationConfig } from './saved_objects_config'; -export { SavedObjectTypeRegistry } from './saved_objects_type_registry'; export { CoreSavedObjectsRouteHandlerContext } from './saved_objects_route_handler_context'; diff --git a/src/core/server/saved_objects/migrations/actions/create_index.ts b/src/core/server/saved_objects/migrations/actions/create_index.ts index 0f6b062a42163..f48918d679624 100644 --- a/src/core/server/saved_objects/migrations/actions/create_index.ts +++ b/src/core/server/saved_objects/migrations/actions/create_index.ts @@ -11,8 +11,8 @@ import * as TaskEither from 'fp-ts/lib/TaskEither'; import { pipe } from 'fp-ts/lib/pipeable'; import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; +import type { IndexMapping } from '@kbn/core-saved-objects-base-server-internal'; import { AcknowledgeResponse } from '.'; -import { IndexMapping } from '../../mappings'; import { catchRetryableEsClientErrors, RetryableEsClientError, diff --git a/src/core/server/saved_objects/migrations/actions/fetch_indices.ts b/src/core/server/saved_objects/migrations/actions/fetch_indices.ts index 922797f2ba268..0eb43380a6990 100644 --- a/src/core/server/saved_objects/migrations/actions/fetch_indices.ts +++ b/src/core/server/saved_objects/migrations/actions/fetch_indices.ts @@ -5,10 +5,11 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ + import * as TaskEither from 'fp-ts/lib/TaskEither'; import * as Either from 'fp-ts/lib/Either'; import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; -import { IndexMapping } from '../../mappings'; +import type { IndexMapping } from '@kbn/core-saved-objects-base-server-internal'; import { catchRetryableEsClientErrors, RetryableEsClientError, diff --git a/src/core/server/saved_objects/migrations/actions/update_and_pickup_mappings.ts b/src/core/server/saved_objects/migrations/actions/update_and_pickup_mappings.ts index bd1c2d6ff7614..a5fe33e9bbcf5 100644 --- a/src/core/server/saved_objects/migrations/actions/update_and_pickup_mappings.ts +++ b/src/core/server/saved_objects/migrations/actions/update_and_pickup_mappings.ts @@ -10,7 +10,7 @@ import * as Either from 'fp-ts/lib/Either'; import * as TaskEither from 'fp-ts/lib/TaskEither'; import { pipe } from 'fp-ts/lib/pipeable'; import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; -import { IndexMapping } from '../../mappings'; +import type { IndexMapping } from '@kbn/core-saved-objects-base-server-internal'; import { catchRetryableEsClientErrors, RetryableEsClientError, 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 7a57a7a8a08d3..7f1542ffc6008 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 @@ -6,7 +6,10 @@ * Side Public License, v 1. */ -import { IndexMapping, SavedObjectsTypeMappingDefinitions } from '../../mappings'; +import type { + IndexMapping, + SavedObjectsTypeMappingDefinitions, +} from '@kbn/core-saved-objects-base-server-internal'; import { buildActiveMappings, diffMappings } from './build_active_mappings'; describe('buildActiveMappings', () => { 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 62f5bd1454419..1a0a502f655bd 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 @@ -13,7 +13,10 @@ import crypto from 'crypto'; import { cloneDeep, mapValues } from 'lodash'; import type { SavedObjectsMappingProperties } from '@kbn/core-saved-objects-server'; -import { IndexMapping, SavedObjectsTypeMappingDefinitions } from '../../mappings'; +import type { + IndexMapping, + SavedObjectsTypeMappingDefinitions, +} from '@kbn/core-saved-objects-base-server-internal'; /** * Creates an index mapping with the core properties required by saved object diff --git a/src/core/server/saved_objects/migrations/core/build_index_map.test.ts b/src/core/server/saved_objects/migrations/core/build_index_map.test.ts index 5f5d587eec359..ec82b0ac2c92f 100644 --- a/src/core/server/saved_objects/migrations/core/build_index_map.test.ts +++ b/src/core/server/saved_objects/migrations/core/build_index_map.test.ts @@ -7,8 +7,8 @@ */ import type { SavedObjectsType } from '@kbn/core-saved-objects-server'; +import { SavedObjectTypeRegistry } from '@kbn/core-saved-objects-base-server-internal'; import { createIndexMap } from './build_index_map'; -import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry'; const createRegistry = (...types: Array>) => { const registry = new SavedObjectTypeRegistry(); 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 1e1adcf0dcbc8..225b3bb422925 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 @@ -7,7 +7,7 @@ */ import type { ISavedObjectTypeRegistry } from '@kbn/core-saved-objects-server'; -import type { SavedObjectsTypeMappingDefinitions } from '../../mappings'; +import type { SavedObjectsTypeMappingDefinitions } from '@kbn/core-saved-objects-base-server-internal'; export interface CreateIndexMapOptions { kibanaIndexName: string; diff --git a/src/core/server/saved_objects/migrations/core/disable_unknown_type_mapping_fields.ts b/src/core/server/saved_objects/migrations/core/disable_unknown_type_mapping_fields.ts index b1e25e6e024fb..8b1eccbe09d78 100644 --- a/src/core/server/saved_objects/migrations/core/disable_unknown_type_mapping_fields.ts +++ b/src/core/server/saved_objects/migrations/core/disable_unknown_type_mapping_fields.ts @@ -7,7 +7,7 @@ */ import type { SavedObjectsMappingProperties } from '@kbn/core-saved-objects-server'; -import { IndexMapping } from '../../mappings'; +import type { IndexMapping } from '@kbn/core-saved-objects-base-server-internal'; /** * Merges the active mappings and the source mappings while disabling the diff --git a/src/core/server/saved_objects/migrations/core/document_migrator.test.mock.ts b/src/core/server/saved_objects/migrations/core/document_migrator.test.mock.ts index ee0b18af5ac0d..df7914a55876f 100644 --- a/src/core/server/saved_objects/migrations/core/document_migrator.test.mock.ts +++ b/src/core/server/saved_objects/migrations/core/document_migrator.test.mock.ts @@ -7,8 +7,9 @@ */ const mockGetConvertedObjectId = jest.fn().mockReturnValue('uuidv5'); -jest.mock('../../service/lib/utils', () => { - const actual = jest.requireActual('../../service/lib/utils'); + +jest.mock('@kbn/core-saved-objects-utils-server', () => { + const actual = jest.requireActual('@kbn/core-saved-objects-utils-server'); return { ...actual, SavedObjectsUtils: { diff --git a/src/core/server/saved_objects/migrations/core/document_migrator.test.ts b/src/core/server/saved_objects/migrations/core/document_migrator.test.ts index 1d12d2062be93..a0dd1cfddc3a4 100644 --- a/src/core/server/saved_objects/migrations/core/document_migrator.test.ts +++ b/src/core/server/saved_objects/migrations/core/document_migrator.test.ts @@ -10,11 +10,13 @@ import { mockGetConvertedObjectId } from './document_migrator.test.mock'; import { set } from '@kbn/safer-lodash-set'; import _ from 'lodash'; import type { SavedObjectUnsanitizedDoc, SavedObjectsType } from '@kbn/core-saved-objects-server'; +import { + SavedObjectTypeRegistry, + LEGACY_URL_ALIAS_TYPE, +} from '@kbn/core-saved-objects-base-server-internal'; import { DocumentMigrator } from './document_migrator'; import { TransformSavedObjectDocumentError } from './transform_saved_object_document_error'; import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; -import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry'; -import { LEGACY_URL_ALIAS_TYPE } from '../../object_types'; const mockLoggerFactory = loggingSystemMock.create(); const mockLogger = mockLoggerFactory.get('mock logger'); diff --git a/src/core/server/saved_objects/migrations/core/document_migrator.ts b/src/core/server/saved_objects/migrations/core/document_migrator.ts index 677b2a685f64e..1040699a99e9d 100644 --- a/src/core/server/saved_objects/migrations/core/document_migrator.ts +++ b/src/core/server/saved_objects/migrations/core/document_migrator.ts @@ -58,10 +58,13 @@ import type { SavedObjectMigrationFn, SavedObjectMigrationMap, } from '@kbn/core-saved-objects-server'; +import { DEFAULT_NAMESPACE_STRING, SavedObjectsUtils } from '@kbn/core-saved-objects-utils-server'; +import { + type LegacyUrlAlias, + LEGACY_URL_ALIAS_TYPE, +} from '@kbn/core-saved-objects-base-server-internal'; import { MigrationLogger } from './migration_logger'; import { TransformSavedObjectDocumentError } from '.'; -import { DEFAULT_NAMESPACE_STRING, SavedObjectsUtils } from '../../service/lib/utils'; -import { LegacyUrlAlias, LEGACY_URL_ALIAS_TYPE } from '../../object_types'; const DEFAULT_MINIMUM_CONVERT_VERSION = '8.0.0'; diff --git a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts index 09ec13bcae05b..c9d7b78953e28 100644 --- a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts +++ b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts @@ -9,8 +9,10 @@ import { set } from '@kbn/safer-lodash-set'; import * as Either from 'fp-ts/lib/Either'; import _ from 'lodash'; -import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry'; -import { SavedObjectsSerializer } from '../../serialization'; +import { + SavedObjectTypeRegistry, + SavedObjectsSerializer, +} from '@kbn/core-saved-objects-base-server-internal'; import { DocumentsTransformFailed, DocumentsTransformSuccess, diff --git a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts index 8534d7e497be0..d1ca65f1dd103 100644 --- a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts +++ b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts @@ -16,7 +16,7 @@ import type { SavedObjectsRawDoc, SavedObjectUnsanitizedDoc, } from '@kbn/core-saved-objects-server'; -import { SavedObjectsSerializer } from '../../serialization'; +import { SavedObjectsSerializer } from '@kbn/core-saved-objects-base-server-internal'; import { MigrateAndConvertFn } from './document_migrator'; import { TransformSavedObjectDocumentError } from '.'; diff --git a/src/core/server/saved_objects/migrations/index.ts b/src/core/server/saved_objects/migrations/index.ts index 54416f423a79a..707b777330ec3 100644 --- a/src/core/server/saved_objects/migrations/index.ts +++ b/src/core/server/saved_objects/migrations/index.ts @@ -9,4 +9,3 @@ export type { MigrationResult } from './core'; export { KibanaMigrator } from './kibana_migrator'; export type { IKibanaMigrator, KibanaMigratorStatus } from './kibana_migrator'; -export { mergeSavedObjectMigrationMaps } from './utils'; diff --git a/src/core/server/saved_objects/migrations/initial_state.test.ts b/src/core/server/saved_objects/migrations/initial_state.test.ts index 32e3b9f50f4a3..6d49b17d4fa80 100644 --- a/src/core/server/saved_objects/migrations/initial_state.test.ts +++ b/src/core/server/saved_objects/migrations/initial_state.test.ts @@ -10,9 +10,11 @@ import { ByteSizeValue } from '@kbn/config-schema'; import * as Option from 'fp-ts/Option'; import type { DocLinksServiceSetup } from '@kbn/core-doc-links-server'; import { docLinksServiceMock } from '@kbn/core-doc-links-server-mocks'; +import { + type SavedObjectsMigrationConfigType, + SavedObjectTypeRegistry, +} from '@kbn/core-saved-objects-base-server-internal'; import { loggingSystemMock } from '../../mocks'; -import { SavedObjectsMigrationConfigType } from '../saved_objects_config'; -import { SavedObjectTypeRegistry } from '../saved_objects_type_registry'; import { createInitialState } from './initial_state'; const mockLogger = loggingSystemMock.create(); diff --git a/src/core/server/saved_objects/migrations/initial_state.ts b/src/core/server/saved_objects/migrations/initial_state.ts index 861ec75e2d875..1843227934bcd 100644 --- a/src/core/server/saved_objects/migrations/initial_state.ts +++ b/src/core/server/saved_objects/migrations/initial_state.ts @@ -11,8 +11,10 @@ import type { DocLinksServiceStart } from '@kbn/core-doc-links-server'; import type { Logger } from '@kbn/logging'; import type { SavedObjectsMigrationVersion } from '@kbn/core-saved-objects-common'; import type { ISavedObjectTypeRegistry } from '@kbn/core-saved-objects-server'; -import type { IndexMapping } from '../mappings'; -import type { SavedObjectsMigrationConfigType } from '../saved_objects_config'; +import type { + IndexMapping, + SavedObjectsMigrationConfigType, +} from '@kbn/core-saved-objects-base-server-internal'; import type { InitState } from './state'; import { excludeUnusedTypesQuery } from './core'; diff --git a/src/core/server/saved_objects/migrations/kibana_migrator.test.ts b/src/core/server/saved_objects/migrations/kibana_migrator.test.ts index 6806e5a9c80a1..5d1cb32eca6d2 100644 --- a/src/core/server/saved_objects/migrations/kibana_migrator.test.ts +++ b/src/core/server/saved_objects/migrations/kibana_migrator.test.ts @@ -12,8 +12,8 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; import type { SavedObjectsType } from '@kbn/core-saved-objects-server'; +import { SavedObjectTypeRegistry } from '@kbn/core-saved-objects-base-server-internal'; import { KibanaMigratorOptions, KibanaMigrator } from './kibana_migrator'; -import { SavedObjectTypeRegistry } from '../saved_objects_type_registry'; import { DocumentMigrator } from './core/document_migrator'; import { ByteSizeValue } from '@kbn/config-schema'; import { docLinksServiceMock } from '@kbn/core-doc-links-server-mocks'; diff --git a/src/core/server/saved_objects/migrations/kibana_migrator.ts b/src/core/server/saved_objects/migrations/kibana_migrator.ts index 146dd600ab4d0..2a8f9a9c3ee0f 100644 --- a/src/core/server/saved_objects/migrations/kibana_migrator.ts +++ b/src/core/server/saved_objects/migrations/kibana_migrator.ts @@ -22,12 +22,15 @@ import type { SavedObjectsRawDoc, ISavedObjectTypeRegistry, } from '@kbn/core-saved-objects-server'; -import { IndexMapping, SavedObjectsTypeMappingDefinitions } from '../mappings'; -import { SavedObjectsSerializer } from '../serialization'; +import { + SavedObjectsSerializer, + type IndexMapping, + type SavedObjectsTypeMappingDefinitions, + type SavedObjectsMigrationConfigType, +} from '@kbn/core-saved-objects-base-server-internal'; import { buildActiveMappings, MigrationResult, MigrationStatus } from './core'; import { DocumentMigrator, VersionedTransformer } from './core/document_migrator'; import { createIndexMap } from './core/build_index_map'; -import { SavedObjectsMigrationConfigType } from '../saved_objects_config'; import { runResilientMigrator } from './run_resilient_migrator'; import { migrateRawDocsSafely } from './core/migrate_raw_docs'; diff --git a/src/core/server/saved_objects/migrations/migrations_state_action_machine.test.ts b/src/core/server/saved_objects/migrations/migrations_state_action_machine.test.ts index db319c63e216f..1c4644fb43325 100644 --- a/src/core/server/saved_objects/migrations/migrations_state_action_machine.test.ts +++ b/src/core/server/saved_objects/migrations/migrations_state_action_machine.test.ts @@ -11,8 +11,8 @@ import { migrationStateActionMachine } from './migrations_state_action_machine'; import { docLinksServiceMock } from '@kbn/core-doc-links-server-mocks'; import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; import { LoggerAdapter } from '@kbn/core-logging-server-internal'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { elasticsearchServiceMock } from '../../mocks'; -import { typeRegistryMock } from '../saved_objects_type_registry.mock'; import * as Either from 'fp-ts/lib/Either'; import * as Option from 'fp-ts/lib/Option'; import { errors } from '@elastic/elasticsearch'; diff --git a/src/core/server/saved_objects/migrations/model/helpers.ts b/src/core/server/saved_objects/migrations/model/helpers.ts index ea28c14f9a5f0..5f84dc01af008 100644 --- a/src/core/server/saved_objects/migrations/model/helpers.ts +++ b/src/core/server/saved_objects/migrations/model/helpers.ts @@ -12,8 +12,8 @@ import type { QueryDslQueryContainer, } from '@elastic/elasticsearch/lib/api/types'; import * as Either from 'fp-ts/lib/Either'; +import type { IndexMapping } from '@kbn/core-saved-objects-base-server-internal'; import type { State } from '../state'; -import type { IndexMapping } from '../../mappings'; import type { FetchIndexResponse } from '../actions'; /** diff --git a/src/core/server/saved_objects/migrations/run_resilient_migrator.ts b/src/core/server/saved_objects/migrations/run_resilient_migrator.ts index 9ca3d3dbaaa60..6a6153b997146 100644 --- a/src/core/server/saved_objects/migrations/run_resilient_migrator.ts +++ b/src/core/server/saved_objects/migrations/run_resilient_migrator.ts @@ -11,14 +11,16 @@ import type { DocLinksServiceStart } from '@kbn/core-doc-links-server'; import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; import type { SavedObjectsMigrationVersion } from '@kbn/core-saved-objects-common'; import type { ISavedObjectTypeRegistry } from '@kbn/core-saved-objects-server'; -import { IndexMapping } from '../mappings'; +import type { + IndexMapping, + SavedObjectsMigrationConfigType, +} from '@kbn/core-saved-objects-base-server-internal'; import type { TransformRawDocs } from './types'; import { MigrationResult } from './core'; import { next } from './next'; import { model } from './model'; import { createInitialState } from './initial_state'; import { migrationStateActionMachine } from './migrations_state_action_machine'; -import { SavedObjectsMigrationConfigType } from '../saved_objects_config'; /** * To avoid the Elasticsearch-js client aborting our requests before we diff --git a/src/core/server/saved_objects/migrations/state.ts b/src/core/server/saved_objects/migrations/state.ts index d94d49ecec7aa..eb8d2e2fbb05b 100644 --- a/src/core/server/saved_objects/migrations/state.ts +++ b/src/core/server/saved_objects/migrations/state.ts @@ -13,9 +13,9 @@ import type { SavedObjectsRawDoc, SavedObjectTypeExcludeFromUpgradeFilterHook, } from '@kbn/core-saved-objects-server'; +import type { IndexMapping } from '@kbn/core-saved-objects-base-server-internal'; import type { ControlState } from './state_action_machine'; import type { AliasAction } from './actions'; -import type { IndexMapping } from '../mappings'; import type { TransformErrorObjects } from './core'; import type { MigrationLog, Progress } from './types'; diff --git a/src/core/server/saved_objects/object_types/index.ts b/src/core/server/saved_objects/object_types/index.ts index 11a2c1973b09a..55c0db7ffcdbc 100644 --- a/src/core/server/saved_objects/object_types/index.ts +++ b/src/core/server/saved_objects/object_types/index.ts @@ -6,6 +6,4 @@ * Side Public License, v 1. */ -export { LEGACY_URL_ALIAS_TYPE } from './constants'; -export type { LegacyUrlAlias } from './types'; export { registerCoreObjectTypes } from './registration'; diff --git a/src/core/server/saved_objects/object_types/registration.test.ts b/src/core/server/saved_objects/object_types/registration.test.ts index 724b9baababef..2c8a467e32842 100644 --- a/src/core/server/saved_objects/object_types/registration.test.ts +++ b/src/core/server/saved_objects/object_types/registration.test.ts @@ -6,8 +6,8 @@ * Side Public License, v 1. */ -import { typeRegistryMock } from '../saved_objects_type_registry.mock'; -import { LEGACY_URL_ALIAS_TYPE } from './constants'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; +import { LEGACY_URL_ALIAS_TYPE } from '@kbn/core-saved-objects-base-server-internal'; import { registerCoreObjectTypes } from './registration'; describe('Core saved object types registration', () => { diff --git a/src/core/server/saved_objects/object_types/registration.ts b/src/core/server/saved_objects/object_types/registration.ts index d93b1cc2e2a23..5d31cb1e03077 100644 --- a/src/core/server/saved_objects/object_types/registration.ts +++ b/src/core/server/saved_objects/object_types/registration.ts @@ -7,9 +7,11 @@ */ import type { ISavedObjectTypeRegistry, SavedObjectsType } from '@kbn/core-saved-objects-server'; -import { LEGACY_URL_ALIAS_TYPE } from './constants'; -import { SavedObjectTypeRegistry } from '..'; -import type { LegacyUrlAlias } from './types'; +import { + SavedObjectTypeRegistry, + LEGACY_URL_ALIAS_TYPE, + type LegacyUrlAlias, +} from '@kbn/core-saved-objects-base-server-internal'; const legacyUrlAliasType: SavedObjectsType = { name: LEGACY_URL_ALIAS_TYPE, diff --git a/src/core/server/saved_objects/routes/export.ts b/src/core/server/saved_objects/routes/export.ts index bd89a2845626a..0ab75a3c7101d 100644 --- a/src/core/server/saved_objects/routes/export.ts +++ b/src/core/server/saved_objects/routes/export.ts @@ -15,8 +15,8 @@ import type { SavedObjectsExportByTypeOptions, SavedObjectsExportByObjectOptions, } from '@kbn/core-saved-objects-server'; +import type { SavedObjectConfig } from '@kbn/core-saved-objects-base-server-internal'; import { InternalCoreUsageDataSetup } from '../../core_usage_data'; -import { SavedObjectConfig } from '../saved_objects_config'; import { SavedObjectsExportError } from '../export'; import type { InternalSavedObjectRouter } from '../internal_types'; import { validateTypes, validateObjects, catchAndReturnBoomErrors } from './utils'; diff --git a/src/core/server/saved_objects/routes/import.ts b/src/core/server/saved_objects/routes/import.ts index 0c56acf9e2d68..717cc50a13e60 100644 --- a/src/core/server/saved_objects/routes/import.ts +++ b/src/core/server/saved_objects/routes/import.ts @@ -9,8 +9,8 @@ import { Readable } from 'stream'; import { extname } from 'path'; import { schema } from '@kbn/config-schema'; +import type { SavedObjectConfig } from '@kbn/core-saved-objects-base-server-internal'; import { InternalCoreUsageDataSetup } from '../../core_usage_data'; -import { SavedObjectConfig } from '../saved_objects_config'; import { SavedObjectsImportError } from '../import'; import type { InternalSavedObjectRouter } from '../internal_types'; import { catchAndReturnBoomErrors, createSavedObjectsStreamFromNdJson } from './utils'; diff --git a/src/core/server/saved_objects/routes/index.ts b/src/core/server/saved_objects/routes/index.ts index edc52efdeaef8..f49c604a37c0c 100644 --- a/src/core/server/saved_objects/routes/index.ts +++ b/src/core/server/saved_objects/routes/index.ts @@ -8,8 +8,8 @@ import type { Logger } from '@kbn/logging'; import type { InternalHttpServiceSetup } from '@kbn/core-http-server-internal'; +import type { SavedObjectConfig } from '@kbn/core-saved-objects-base-server-internal'; import { InternalCoreUsageDataSetup } from '../../core_usage_data'; -import { SavedObjectConfig } from '../saved_objects_config'; import { IKibanaMigrator } from '../migrations'; import type { InternalSavedObjectsRequestHandlerContext } from '../internal_types'; import { registerGetRoute } from './get'; diff --git a/src/core/server/saved_objects/routes/resolve_import_errors.ts b/src/core/server/saved_objects/routes/resolve_import_errors.ts index 4bedec1715a4f..ed919693e1b86 100644 --- a/src/core/server/saved_objects/routes/resolve_import_errors.ts +++ b/src/core/server/saved_objects/routes/resolve_import_errors.ts @@ -8,10 +8,10 @@ import { extname } from 'path'; import { Readable } from 'stream'; -import { schema } from '@kbn/config-schema'; import { chain } from 'lodash'; +import { schema } from '@kbn/config-schema'; +import type { SavedObjectConfig } from '@kbn/core-saved-objects-base-server-internal'; import { InternalCoreUsageDataSetup } from '../../core_usage_data'; -import { SavedObjectConfig } from '../saved_objects_config'; import { SavedObjectsImportError } from '../import'; import type { InternalSavedObjectRouter } from '../internal_types'; import { catchAndReturnBoomErrors, createSavedObjectsStreamFromNdJson } from './utils'; 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 292e39b0c199d..f1a1ce6c091b6 100644 --- a/src/core/server/saved_objects/saved_objects_service.mock.ts +++ b/src/core/server/saved_objects/saved_objects_service.mock.ts @@ -21,7 +21,7 @@ import type { import { savedObjectsRepositoryMock } from './service/lib/repository.mock'; import { savedObjectsClientMock } from './service/saved_objects_client.mock'; -import { typeRegistryMock } from './saved_objects_type_registry.mock'; +import { typeRegistryMock, serializerMock } from '@kbn/core-saved-objects-base-server-mocks'; import { savedObjectsExporterMock } from './export/saved_objects_exporter.mock'; import { savedObjectsImporterMock } from './import/saved_objects_importer.mock'; import { migrationMocks } from './migrations/mocks'; @@ -105,4 +105,5 @@ export const savedObjectsServiceMock = { createTypeRegistryMock: typeRegistryMock.create, createExporter: savedObjectsExporterMock.create, createImporter: savedObjectsImporterMock.create, + createSerializer: serializerMock.create, }; diff --git a/src/core/server/saved_objects/saved_objects_service.test.mocks.ts b/src/core/server/saved_objects/saved_objects_service.test.mocks.ts index f4b58fd12d8ba..4b66f5865def5 100644 --- a/src/core/server/saved_objects/saved_objects_service.test.mocks.ts +++ b/src/core/server/saved_objects/saved_objects_service.test.mocks.ts @@ -8,7 +8,7 @@ import { mockKibanaMigrator } from './migrations/kibana_migrator.mock'; import { savedObjectsClientProviderMock } from './service/lib/scoped_client_provider.mock'; -import { typeRegistryMock } from './saved_objects_type_registry.mock'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; export const migratorInstanceMock = mockKibanaMigrator.create(); export const KibanaMigratorMock = jest.fn().mockImplementation(() => migratorInstanceMock); @@ -22,15 +22,15 @@ jest.doMock('./service/lib/scoped_client_provider', () => ({ })); export const typeRegistryInstanceMock = typeRegistryMock.create(); -jest.doMock('./saved_objects_type_registry', () => ({ - SavedObjectTypeRegistry: jest.fn().mockImplementation(() => typeRegistryInstanceMock), -})); +jest.doMock('@kbn/core-saved-objects-base-server-internal', () => { + const actual = jest.requireActual('@kbn/core-saved-objects-base-server-internal'); + return { + ...actual, + SavedObjectTypeRegistry: jest.fn().mockImplementation(() => typeRegistryInstanceMock), + }; +}); export const registerRoutesMock = jest.fn(); jest.doMock('./routes', () => ({ registerRoutes: registerRoutesMock, })); - -// The SavedObjectsSerializer imports SavedObjectUtils from the '../service' module, and that somehow breaks unit tests for the -// SavedObjectsService. To avoid this, we mock the entire './serialization' module, since we don't need it for these tests. -jest.mock('./serialization'); diff --git a/src/core/server/saved_objects/saved_objects_service.ts b/src/core/server/saved_objects/saved_objects_service.ts index 53eb376cc37b7..542a13e3a4cc0 100644 --- a/src/core/server/saved_objects/saved_objects_service.ts +++ b/src/core/server/saved_objects/saved_objects_service.ts @@ -27,18 +27,18 @@ import type { SavedObjectsClientWrapperFactory, ISavedObjectTypeRegistry, } from '@kbn/core-saved-objects-server'; +import { + SavedObjectConfig, + SavedObjectsSerializer, + SavedObjectTypeRegistry, + type SavedObjectsConfigType, + type SavedObjectsMigrationConfigType, +} from '@kbn/core-saved-objects-base-server-internal'; import { SavedObjectsClient, SavedObjectsClientProvider } from './service'; import { KibanaMigrator, IKibanaMigrator } from './migrations'; import { InternalCoreUsageDataSetup } from '../core_usage_data'; import { InternalDeprecationsServiceSetup } from '../deprecations'; -import { - SavedObjectsConfigType, - SavedObjectsMigrationConfigType, - SavedObjectConfig, -} from './saved_objects_config'; import { SavedObjectsRepository } from './service/lib/repository'; -import { SavedObjectTypeRegistry } from './saved_objects_type_registry'; -import { SavedObjectsSerializer } from './serialization'; import { SavedObjectsExporter } from './export'; import { SavedObjectsImporter } from './import'; import { registerRoutes } from './routes'; diff --git a/src/core/server/saved_objects/service/index.ts b/src/core/server/saved_objects/service/index.ts index 1ce638c4c0188..0737fc725d1a4 100644 --- a/src/core/server/saved_objects/service/index.ts +++ b/src/core/server/saved_objects/service/index.ts @@ -5,6 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -export { SavedObjectsErrorHelpers, SavedObjectsClientProvider, SavedObjectsUtils } from './lib'; + +export { SavedObjectsClientProvider } from './lib'; export type { SavedObjectsRepository, ISavedObjectsClientProvider } from './lib'; export { SavedObjectsClient } from './saved_objects_client'; diff --git a/src/core/server/saved_objects/service/lib/aggregations/validation.ts b/src/core/server/saved_objects/service/lib/aggregations/validation.ts index 76098d73306af..b3a6bbae5e956 100644 --- a/src/core/server/saved_objects/service/lib/aggregations/validation.ts +++ b/src/core/server/saved_objects/service/lib/aggregations/validation.ts @@ -10,7 +10,7 @@ import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { ObjectType } from '@kbn/config-schema'; import { isPlainObject, isArray } from 'lodash'; -import { IndexMapping } from '../../../mappings'; +import type { IndexMapping } from '@kbn/core-saved-objects-base-server-internal'; import { isObjectTypeAttribute, rewriteObjectTypeAttribute, diff --git a/src/core/server/saved_objects/service/lib/aggregations/validation_utils.ts b/src/core/server/saved_objects/service/lib/aggregations/validation_utils.ts index 0b2cc8e235c9c..5548ad4d57a5d 100644 --- a/src/core/server/saved_objects/service/lib/aggregations/validation_utils.ts +++ b/src/core/server/saved_objects/service/lib/aggregations/validation_utils.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { IndexMapping } from '../../../mappings'; +import type { IndexMapping } from '@kbn/core-saved-objects-base-server-internal'; import { fieldDefined, hasFilterKeyError } from '../filter_utils'; /** diff --git a/src/core/server/saved_objects/service/lib/collect_multi_namespace_references.test.ts b/src/core/server/saved_objects/service/lib/collect_multi_namespace_references.test.ts index d3cf76716e598..86e1e82d12a6f 100644 --- a/src/core/server/saved_objects/service/lib/collect_multi_namespace_references.test.ts +++ b/src/core/server/saved_objects/service/lib/collect_multi_namespace_references.test.ts @@ -17,15 +17,15 @@ import type { SavedObjectsCollectMultiNamespaceReferencesObject, SavedObjectsCollectMultiNamespaceReferencesOptions, } from '@kbn/core-saved-objects-api-server'; -import { typeRegistryMock } from '../../saved_objects_type_registry.mock'; -import { SavedObjectsSerializer } from '../../serialization'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; +import { SavedObjectsSerializer } from '@kbn/core-saved-objects-base-server-internal'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { ALIAS_OR_SHARED_ORIGIN_SEARCH_PER_PAGE, CollectMultiNamespaceReferencesParams, } from './collect_multi_namespace_references'; import { collectMultiNamespaceReferences } from './collect_multi_namespace_references'; import type { CreatePointInTimeFinderFn } from './point_in_time_finder'; -import { SavedObjectsErrorHelpers } from './errors'; const SPACES = ['default', 'another-space']; const VERSION_PROPS = { _seq_no: 1, _primary_term: 1 }; diff --git a/src/core/server/saved_objects/service/lib/collect_multi_namespace_references.ts b/src/core/server/saved_objects/service/lib/collect_multi_namespace_references.ts index b31f817e4c4d2..222b58d3a03e0 100644 --- a/src/core/server/saved_objects/service/lib/collect_multi_namespace_references.ts +++ b/src/core/server/saved_objects/service/lib/collect_multi_namespace_references.ts @@ -15,8 +15,8 @@ import type { SavedObjectReferenceWithContext, } from '@kbn/core-saved-objects-api-server'; import type { ISavedObjectTypeRegistry } from '@kbn/core-saved-objects-server'; -import type { SavedObjectsSerializer } from '../../serialization'; -import { SavedObjectsErrorHelpers } from './errors'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; +import type { SavedObjectsSerializer } from '@kbn/core-saved-objects-base-server-internal'; import { findLegacyUrlAliases } from './legacy_url_aliases'; import { getRootFields } from './included_fields'; import { diff --git a/src/core/server/saved_objects/service/lib/decorate_es_error.test.ts b/src/core/server/saved_objects/service/lib/decorate_es_error.test.ts index a7aa52f7a0f5a..8290f7345190d 100644 --- a/src/core/server/saved_objects/service/lib/decorate_es_error.test.ts +++ b/src/core/server/saved_objects/service/lib/decorate_es_error.test.ts @@ -8,8 +8,8 @@ import { errors as esErrors } from '@elastic/elasticsearch'; import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import { decorateEsError } from './decorate_es_error'; -import { SavedObjectsErrorHelpers } from './errors'; describe('savedObjectsClient/decorateEsError', () => { it('always returns the same error it receives', () => { diff --git a/src/core/server/saved_objects/service/lib/decorate_es_error.ts b/src/core/server/saved_objects/service/lib/decorate_es_error.ts index 40eda7a854a25..9cfdffc13a5dd 100644 --- a/src/core/server/saved_objects/service/lib/decorate_es_error.ts +++ b/src/core/server/saved_objects/service/lib/decorate_es_error.ts @@ -10,6 +10,7 @@ import { get } from 'lodash'; import { errors as esErrors } from '@elastic/elasticsearch'; import type { ElasticsearchErrorDetails } from '@kbn/es-errors'; import { isSupportedEsServer } from '@kbn/core-elasticsearch-server-internal'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; const responseErrors = { isServiceUnavailable: (statusCode?: number) => statusCode === 503, @@ -25,8 +26,6 @@ const { ConnectionError, NoLivingConnectionsError, TimeoutError } = esErrors; const SCRIPT_CONTEXT_DISABLED_REGEX = /(?:cannot execute scripts using \[)([a-z]*)(?:\] context)/; const INLINE_SCRIPTS_DISABLED_MESSAGE = 'cannot execute [inline] scripts'; -import { SavedObjectsErrorHelpers } from './errors'; - type EsErrors = | esErrors.ConnectionError | esErrors.NoLivingConnectionsError diff --git a/src/core/server/saved_objects/service/lib/filter_utils.ts b/src/core/server/saved_objects/service/lib/filter_utils.ts index 30880368d096d..ae7bb08039850 100644 --- a/src/core/server/saved_objects/service/lib/filter_utils.ts +++ b/src/core/server/saved_objects/service/lib/filter_utils.ts @@ -9,8 +9,8 @@ import { set } from '@kbn/safer-lodash-set'; import { get, cloneDeep } from 'lodash'; import * as esKuery from '@kbn/es-query'; -import { SavedObjectsErrorHelpers } from './errors'; -import { IndexMapping } from '../../mappings'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; +import type { IndexMapping } from '@kbn/core-saved-objects-base-server-internal'; type KueryNode = any; diff --git a/src/core/server/saved_objects/service/lib/find_shared_origin_objects.ts b/src/core/server/saved_objects/service/lib/find_shared_origin_objects.ts index 229e0c6f90a66..34aff0b11d6d0 100644 --- a/src/core/server/saved_objects/service/lib/find_shared_origin_objects.ts +++ b/src/core/server/saved_objects/service/lib/find_shared_origin_objects.ts @@ -7,9 +7,9 @@ */ import * as esKuery from '@kbn/es-query'; +import { ALL_NAMESPACES_STRING } from '@kbn/core-saved-objects-utils-server'; import { getObjectKey } from './internal_utils'; import type { CreatePointInTimeFinderFn } from './point_in_time_finder'; -import { ALL_NAMESPACES_STRING } from './utils'; interface ObjectOrigin { /** The object's type. */ diff --git a/src/core/server/saved_objects/service/lib/get_index_for_type.test.ts b/src/core/server/saved_objects/service/lib/get_index_for_type.test.ts index 16e3ba9495f04..01bb3174cc56b 100644 --- a/src/core/server/saved_objects/service/lib/get_index_for_type.test.ts +++ b/src/core/server/saved_objects/service/lib/get_index_for_type.test.ts @@ -6,8 +6,8 @@ * Side Public License, v 1. */ +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { getIndexForType } from './get_index_for_type'; -import { typeRegistryMock } from '../../saved_objects_type_registry.mock'; describe('getIndexForType', () => { const kibanaVersion = '8.0.0'; diff --git a/src/core/server/saved_objects/service/lib/index.ts b/src/core/server/saved_objects/service/lib/index.ts index 8fdb8301ce101..a43750608bf95 100644 --- a/src/core/server/saved_objects/service/lib/index.ts +++ b/src/core/server/saved_objects/service/lib/index.ts @@ -11,8 +11,4 @@ export { SavedObjectsClientProvider } from './scoped_client_provider'; export type { ISavedObjectsClientProvider } from './scoped_client_provider'; -export { SavedObjectsErrorHelpers } from './errors'; - -export { SavedObjectsUtils } from './utils'; - export { getIndexForType } from './get_index_for_type'; diff --git a/src/core/server/saved_objects/service/lib/internal_bulk_resolve.test.ts b/src/core/server/saved_objects/service/lib/internal_bulk_resolve.test.ts index ec55ea7725718..119b3ac85b698 100644 --- a/src/core/server/saved_objects/service/lib/internal_bulk_resolve.test.ts +++ b/src/core/server/saved_objects/service/lib/internal_bulk_resolve.test.ts @@ -18,12 +18,13 @@ import type { SavedObjectsBulkResolveObject, SavedObjectsBaseOptions, } from '@kbn/core-saved-objects-api-server'; -import { LEGACY_URL_ALIAS_TYPE } from '../../object_types'; -import { typeRegistryMock } from '../../saved_objects_type_registry.mock'; -import { SavedObjectsSerializer } from '../../serialization'; -import { SavedObjectsErrorHelpers } from './errors'; +import { SavedObjectsErrorHelpers, SavedObjectsUtils } from '@kbn/core-saved-objects-utils-server'; +import { + SavedObjectsSerializer, + LEGACY_URL_ALIAS_TYPE, +} from '@kbn/core-saved-objects-base-server-internal'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { internalBulkResolve, InternalBulkResolveParams } from './internal_bulk_resolve'; -import { SavedObjectsUtils } from './utils'; import { normalizeNamespace } from './internal_utils'; const VERSION_PROPS = { _seq_no: 1, _primary_term: 1 }; diff --git a/src/core/server/saved_objects/service/lib/internal_bulk_resolve.ts b/src/core/server/saved_objects/service/lib/internal_bulk_resolve.ts index ebe94e4e95b4d..b15fc56e2f3c0 100644 --- a/src/core/server/saved_objects/service/lib/internal_bulk_resolve.ts +++ b/src/core/server/saved_objects/service/lib/internal_bulk_resolve.ts @@ -21,14 +21,20 @@ import type { ISavedObjectTypeRegistry, SavedObjectsRawDocSource, } from '@kbn/core-saved-objects-server'; +import { + SavedObjectsErrorHelpers, + type DecoratedError, +} from '@kbn/core-saved-objects-utils-server'; +import { + LEGACY_URL_ALIAS_TYPE, + type LegacyUrlAlias, + type SavedObjectsSerializer, +} from '@kbn/core-saved-objects-base-server-internal'; import { CORE_USAGE_STATS_ID, CORE_USAGE_STATS_TYPE, REPOSITORY_RESOLVE_OUTCOME_STATS, } from '../../../core_usage_data'; -import { LegacyUrlAlias, LEGACY_URL_ALIAS_TYPE } from '../../object_types'; -import type { SavedObjectsSerializer } from '../../serialization'; -import { DecoratedError, SavedObjectsErrorHelpers } from './errors'; import { getCurrentTime, getSavedObjectFromSource, diff --git a/src/core/server/saved_objects/service/lib/internal_utils.test.ts b/src/core/server/saved_objects/service/lib/internal_utils.test.ts index 65cb83d3e8a77..96ca3949a4775 100644 --- a/src/core/server/saved_objects/service/lib/internal_utils.test.ts +++ b/src/core/server/saved_objects/service/lib/internal_utils.test.ts @@ -7,8 +7,9 @@ */ import type { SavedObjectsRawDoc } from '@kbn/core-saved-objects-server'; -import { typeRegistryMock } from '../../saved_objects_type_registry.mock'; -import { encodeHitVersion } from '../../version'; +import { ALL_NAMESPACES_STRING } from '@kbn/core-saved-objects-utils-server'; +import { encodeHitVersion } from '@kbn/core-saved-objects-base-server-internal'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { getBulkOperationError, getCurrentTime, @@ -19,7 +20,6 @@ import { rawDocExistsInNamespace, rawDocExistsInNamespaces, } from './internal_utils'; -import { ALL_NAMESPACES_STRING } from './utils'; describe('#getBulkOperationError', () => { const type = 'obj-type'; diff --git a/src/core/server/saved_objects/service/lib/internal_utils.ts b/src/core/server/saved_objects/service/lib/internal_utils.ts index 5f20a2bc3c842..84539510504a2 100644 --- a/src/core/server/saved_objects/service/lib/internal_utils.ts +++ b/src/core/server/saved_objects/service/lib/internal_utils.ts @@ -13,9 +13,15 @@ import type { SavedObjectsRawDoc, SavedObjectsRawDocSource, } from '@kbn/core-saved-objects-server'; -import { decodeRequestVersion, encodeHitVersion } from '../../version'; -import { SavedObjectsErrorHelpers } from './errors'; -import { ALL_NAMESPACES_STRING, SavedObjectsUtils } from './utils'; +import { + SavedObjectsErrorHelpers, + SavedObjectsUtils, + ALL_NAMESPACES_STRING, +} from '@kbn/core-saved-objects-utils-server'; +import { + decodeRequestVersion, + encodeHitVersion, +} from '@kbn/core-saved-objects-base-server-internal'; /** * Discriminated union (TypeScript approximation of an algebraic data type); this design pattern is used for internal repository operations. diff --git a/src/core/server/saved_objects/service/lib/legacy_url_aliases/delete_legacy_url_aliases.test.ts b/src/core/server/saved_objects/service/lib/legacy_url_aliases/delete_legacy_url_aliases.test.ts index dc261ee23aafb..77a538672ff19 100644 --- a/src/core/server/saved_objects/service/lib/legacy_url_aliases/delete_legacy_url_aliases.test.ts +++ b/src/core/server/saved_objects/service/lib/legacy_url_aliases/delete_legacy_url_aliases.test.ts @@ -11,8 +11,8 @@ import { mockGetEsErrorMessage } from './delete_legacy_url_aliases.test.mock'; / import { errors as EsErrors } from '@elastic/elasticsearch'; import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; -import { typeRegistryMock } from '../../../saved_objects_type_registry.mock'; -import { ALL_NAMESPACES_STRING } from '../utils'; +import { ALL_NAMESPACES_STRING } from '@kbn/core-saved-objects-utils-server'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { deleteLegacyUrlAliases } from './delete_legacy_url_aliases'; import type { DeleteLegacyUrlAliasesParams } from './delete_legacy_url_aliases'; diff --git a/src/core/server/saved_objects/service/lib/legacy_url_aliases/delete_legacy_url_aliases.ts b/src/core/server/saved_objects/service/lib/legacy_url_aliases/delete_legacy_url_aliases.ts index 873f4ab9b6c9c..73489308f59af 100644 --- a/src/core/server/saved_objects/service/lib/legacy_url_aliases/delete_legacy_url_aliases.ts +++ b/src/core/server/saved_objects/service/lib/legacy_url_aliases/delete_legacy_url_aliases.ts @@ -10,11 +10,13 @@ import * as esKuery from '@kbn/es-query'; import { getErrorMessage as getEsErrorMessage } from '@kbn/core-elasticsearch-client-server-internal'; import type { ISavedObjectTypeRegistry } from '@kbn/core-saved-objects-server'; -import type { IndexMapping } from '../../../mappings'; -import { LEGACY_URL_ALIAS_TYPE } from '../../../object_types'; +import { ALL_NAMESPACES_STRING } from '@kbn/core-saved-objects-utils-server'; +import { + LEGACY_URL_ALIAS_TYPE, + type IndexMapping, +} from '@kbn/core-saved-objects-base-server-internal'; import type { RepositoryEsClient } from '../repository_es_client'; import { getSearchDsl } from '../search_dsl'; -import { ALL_NAMESPACES_STRING } from '../utils'; /** @internal */ export interface DeleteLegacyUrlAliasesParams { diff --git a/src/core/server/saved_objects/service/lib/legacy_url_aliases/find_legacy_url_aliases.test.ts b/src/core/server/saved_objects/service/lib/legacy_url_aliases/find_legacy_url_aliases.test.ts index 8200c7502fec6..36435b9828be4 100644 --- a/src/core/server/saved_objects/service/lib/legacy_url_aliases/find_legacy_url_aliases.test.ts +++ b/src/core/server/saved_objects/service/lib/legacy_url_aliases/find_legacy_url_aliases.test.ts @@ -9,7 +9,10 @@ import type { DeeplyMockedKeys } from '@kbn/utility-types-jest'; import type { ISavedObjectsRepository } from '@kbn/core-saved-objects-api-server'; -import { LegacyUrlAlias, LEGACY_URL_ALIAS_TYPE } from '../../../object_types'; +import { + type LegacyUrlAlias, + LEGACY_URL_ALIAS_TYPE, +} from '@kbn/core-saved-objects-base-server-internal'; import type { CreatePointInTimeFinderFn, PointInTimeFinder } from '../point_in_time_finder'; import { savedObjectsPointInTimeFinderMock } from '../point_in_time_finder.mock'; import { savedObjectsRepositoryMock } from '../repository.mock'; diff --git a/src/core/server/saved_objects/service/lib/legacy_url_aliases/find_legacy_url_aliases.ts b/src/core/server/saved_objects/service/lib/legacy_url_aliases/find_legacy_url_aliases.ts index 70b1730ec8f48..5a90a2e70d073 100644 --- a/src/core/server/saved_objects/service/lib/legacy_url_aliases/find_legacy_url_aliases.ts +++ b/src/core/server/saved_objects/service/lib/legacy_url_aliases/find_legacy_url_aliases.ts @@ -7,7 +7,10 @@ */ import * as esKuery from '@kbn/es-query'; -import { LegacyUrlAlias, LEGACY_URL_ALIAS_TYPE } from '../../../object_types'; +import { + type LegacyUrlAlias, + LEGACY_URL_ALIAS_TYPE, +} from '@kbn/core-saved-objects-base-server-internal'; import { getObjectKey } from '../internal_utils'; import type { CreatePointInTimeFinderFn } from '../point_in_time_finder'; diff --git a/src/core/server/saved_objects/service/lib/preflight_check_for_create.test.ts b/src/core/server/saved_objects/service/lib/preflight_check_for_create.test.ts index 9563ebd51344f..d23d2cf5e804e 100644 --- a/src/core/server/saved_objects/service/lib/preflight_check_for_create.test.ts +++ b/src/core/server/saved_objects/service/lib/preflight_check_for_create.test.ts @@ -15,9 +15,11 @@ import type { DeeplyMockedKeys } from '@kbn/utility-types-jest'; import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; -import { LEGACY_URL_ALIAS_TYPE } from '../../object_types'; -import { typeRegistryMock } from '../../saved_objects_type_registry.mock'; -import { SavedObjectsSerializer } from '../../serialization'; +import { + SavedObjectsSerializer, + LEGACY_URL_ALIAS_TYPE, +} from '@kbn/core-saved-objects-base-server-internal'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import type { CreatePointInTimeFinderFn } from './point_in_time_finder'; import { ALIAS_SEARCH_PER_PAGE, diff --git a/src/core/server/saved_objects/service/lib/preflight_check_for_create.ts b/src/core/server/saved_objects/service/lib/preflight_check_for_create.ts index b94302b2b990f..a3fd4218c3eeb 100644 --- a/src/core/server/saved_objects/service/lib/preflight_check_for_create.ts +++ b/src/core/server/saved_objects/service/lib/preflight_check_for_create.ts @@ -13,15 +13,20 @@ import type { SavedObjectsRawDoc, SavedObjectsRawDocSource, } from '@kbn/core-saved-objects-server'; -import { LegacyUrlAlias, LEGACY_URL_ALIAS_TYPE } from '../../object_types'; -import type { SavedObjectsSerializer } from '../../serialization'; +import { + SavedObjectsErrorHelpers, + ALL_NAMESPACES_STRING, +} from '@kbn/core-saved-objects-utils-server'; +import { + LEGACY_URL_ALIAS_TYPE, + type LegacyUrlAlias, + type SavedObjectsSerializer, +} from '@kbn/core-saved-objects-base-server-internal'; import { findLegacyUrlAliases } from './legacy_url_aliases'; import { Either, rawDocExistsInNamespaces } from './internal_utils'; import { getObjectKey, isLeft, isRight } from './internal_utils'; import type { CreatePointInTimeFinderFn } from './point_in_time_finder'; import type { RepositoryEsClient } from './repository_es_client'; -import { ALL_NAMESPACES_STRING } from './utils'; -import { SavedObjectsErrorHelpers } from './errors'; /** * If the object will be created in this many spaces (or "*" all current and future spaces), we use find to fetch all aliases. diff --git a/src/core/server/saved_objects/service/lib/repository.test.ts b/src/core/server/saved_objects/service/lib/repository.test.ts index 9af620101ab94..30a6b1ab36151 100644 --- a/src/core/server/saved_objects/service/lib/repository.test.ts +++ b/src/core/server/saved_objects/service/lib/repository.test.ts @@ -55,17 +55,21 @@ import type { SavedObjectsMappingProperties, SavedObjectsTypeMappingDefinition, } from '@kbn/core-saved-objects-server'; +import { + SavedObjectsErrorHelpers, + ALL_NAMESPACES_STRING, +} from '@kbn/core-saved-objects-utils-server'; import { SavedObjectsRepository } from './repository'; -import { SavedObjectsErrorHelpers } from './errors'; import { PointInTimeFinder } from './point_in_time_finder'; -import { ALL_NAMESPACES_STRING } from './utils'; import { loggerMock } from '@kbn/logging-mocks'; -import { SavedObjectsSerializer } from '../../serialization'; -import { encodeHitVersion } from '../../version'; -import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry'; +import { + SavedObjectTypeRegistry, + SavedObjectsSerializer, + encodeHitVersion, + LEGACY_URL_ALIAS_TYPE, +} from '@kbn/core-saved-objects-base-server-internal'; import { DocumentMigrator } from '../../migrations/core/document_migrator'; import { mockKibanaMigrator } from '../../migrations/kibana_migrator.mock'; -import { LEGACY_URL_ALIAS_TYPE } from '../../object_types'; import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; import * as esKuery from '@kbn/es-query'; import { errors as EsErrors } from '@elastic/elasticsearch'; diff --git a/src/core/server/saved_objects/service/lib/repository.ts b/src/core/server/saved_objects/service/lib/repository.ts index 1ede13e1142b2..524fe5f7eb966 100644 --- a/src/core/server/saved_objects/service/lib/repository.ts +++ b/src/core/server/saved_objects/service/lib/repository.ts @@ -60,17 +60,31 @@ import type { SavedObjectsRawDocSource, ISavedObjectTypeRegistry, } from '@kbn/core-saved-objects-server'; -import { getRootPropertiesObjects, IndexMapping } from '../../mappings'; +import { + SavedObjectsErrorHelpers, + type DecoratedError, +} from '@kbn/core-saved-objects-utils-server'; +import { + ALL_NAMESPACES_STRING, + FIND_DEFAULT_PAGE, + FIND_DEFAULT_PER_PAGE, + SavedObjectsUtils, +} from '@kbn/core-saved-objects-utils-server'; +import { + SavedObjectsSerializer, + SavedObjectsTypeValidator, + decodeRequestVersion, + encodeVersion, + encodeHitVersion, + getRootPropertiesObjects, + LEGACY_URL_ALIAS_TYPE, + type IndexMapping, +} from '@kbn/core-saved-objects-base-server-internal'; import { PointInTimeFinder } from './point_in_time_finder'; import { createRepositoryEsClient, RepositoryEsClient } from './repository_es_client'; import { getSearchDsl } from './search_dsl'; import { includedFields } from './included_fields'; -import { SavedObjectsErrorHelpers, DecoratedError } from './errors'; -import { decodeRequestVersion, encodeVersion, encodeHitVersion } from '../../version'; import { IKibanaMigrator } from '../../migrations'; -import { SavedObjectsSerializer } from '../../serialization'; -import { LEGACY_URL_ALIAS_TYPE } from '../../object_types'; -import { SavedObjectsTypeValidator } from '../../validation'; import { internalBulkResolve, InternalBulkResolveError } from './internal_bulk_resolve'; import { validateConvertFilterToKueryNode } from './filter_utils'; import { validateAndConvertAggregations } from './aggregations'; @@ -86,12 +100,6 @@ import { isLeft, isRight, } from './internal_utils'; -import { - ALL_NAMESPACES_STRING, - FIND_DEFAULT_PAGE, - FIND_DEFAULT_PER_PAGE, - SavedObjectsUtils, -} from './utils'; import { collectMultiNamespaceReferences } from './collect_multi_namespace_references'; import { updateObjectsSpaces } from './update_objects_spaces'; import { getIndexForType } from './get_index_for_type'; 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 b1033012a4beb..9a2d56cdaaa89 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 @@ -6,10 +6,10 @@ * Side Public License, v 1. */ +import { SavedObjectTypeRegistry } from '@kbn/core-saved-objects-base-server-internal'; import { SavedObjectsRepository } from './repository'; import { mockKibanaMigrator } from '../../migrations/kibana_migrator.mock'; import { KibanaMigrator } from '../../migrations'; -import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry'; import { loggerMock, MockedLogger } from '@kbn/logging-mocks'; jest.mock('./repository'); diff --git a/src/core/server/saved_objects/service/lib/repository_es_client.test.ts b/src/core/server/saved_objects/service/lib/repository_es_client.test.ts index f465ffb6a3dab..cbd8f81bfc0f5 100644 --- a/src/core/server/saved_objects/service/lib/repository_es_client.test.ts +++ b/src/core/server/saved_objects/service/lib/repository_es_client.test.ts @@ -10,7 +10,7 @@ import { retryCallClusterMock } from './repository_es_client.test.mock'; import { createRepositoryEsClient, RepositoryEsClient } from './repository_es_client'; import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; -import { SavedObjectsErrorHelpers } from './errors'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; describe('RepositoryEsClient', () => { let client: ReturnType; diff --git a/src/core/server/saved_objects/service/lib/scoped_client_provider.test.ts b/src/core/server/saved_objects/service/lib/scoped_client_provider.test.ts index efc04f69e6ecf..2641ecfb1cec6 100644 --- a/src/core/server/saved_objects/service/lib/scoped_client_provider.test.ts +++ b/src/core/server/saved_objects/service/lib/scoped_client_provider.test.ts @@ -7,8 +7,8 @@ */ import { httpServerMock } from '@kbn/core-http-server-mocks'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import { SavedObjectsClientProvider } from './scoped_client_provider'; -import { typeRegistryMock } from '../../saved_objects_type_registry.mock'; test(`uses default client factory when one isn't set`, () => { const returnValue = Symbol(); diff --git a/src/core/server/saved_objects/service/lib/search_dsl/query_params.test.ts b/src/core/server/saved_objects/service/lib/search_dsl/query_params.test.ts index 3f27bef5c68af..c502665468e6c 100644 --- a/src/core/server/saved_objects/service/lib/search_dsl/query_params.test.ts +++ b/src/core/server/saved_objects/service/lib/search_dsl/query_params.test.ts @@ -12,8 +12,11 @@ import * as esKuery from '@kbn/es-query'; type KueryNode = any; -import { ALL_NAMESPACES_STRING, DEFAULT_NAMESPACE_STRING } from '../utils'; -import { SavedObjectTypeRegistry } from '../../../saved_objects_type_registry'; +import { + ALL_NAMESPACES_STRING, + DEFAULT_NAMESPACE_STRING, +} from '@kbn/core-saved-objects-utils-server'; +import { SavedObjectTypeRegistry } from '@kbn/core-saved-objects-base-server-internal'; import { getQueryParams } from './query_params'; const registerTypes = (registry: SavedObjectTypeRegistry) => { diff --git a/src/core/server/saved_objects/service/lib/search_dsl/query_params.ts b/src/core/server/saved_objects/service/lib/search_dsl/query_params.ts index 1c21a7177faf4..669f2a273569b 100644 --- a/src/core/server/saved_objects/service/lib/search_dsl/query_params.ts +++ b/src/core/server/saved_objects/service/lib/search_dsl/query_params.ts @@ -11,7 +11,10 @@ import * as esKuery from '@kbn/es-query'; type KueryNode = any; import type { ISavedObjectTypeRegistry } from '@kbn/core-saved-objects-server'; -import { ALL_NAMESPACES_STRING, DEFAULT_NAMESPACE_STRING } from '../utils'; +import { + ALL_NAMESPACES_STRING, + DEFAULT_NAMESPACE_STRING, +} from '@kbn/core-saved-objects-utils-server'; import { getReferencesFilter } from './references_filter'; /** diff --git a/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.test.ts b/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.test.ts index b15560b82ab31..d1ed7251b2414 100644 --- a/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.test.ts +++ b/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.test.ts @@ -10,7 +10,7 @@ jest.mock('./pit_params'); jest.mock('./query_params'); jest.mock('./sorting_params'); -import { typeRegistryMock } from '../../../saved_objects_type_registry.mock'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import * as pitParamsNS from './pit_params'; import * as queryParamsNS from './query_params'; import { getSearchDsl } from './search_dsl'; diff --git a/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.ts b/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.ts index 7d6d31949739c..980bf800755b9 100644 --- a/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.ts +++ b/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.ts @@ -11,7 +11,7 @@ import Boom from '@hapi/boom'; import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { SavedObjectsPitParams } from '@kbn/core-saved-objects-api-server'; import type { ISavedObjectTypeRegistry } from '@kbn/core-saved-objects-server'; -import { IndexMapping } from '../../../mappings'; +import type { IndexMapping } from '@kbn/core-saved-objects-base-server-internal'; import { getQueryParams, HasReferenceQueryParams, SearchOperator } from './query_params'; import { getPitParams } from './pit_params'; import { getSortingParams } from './sorting_params'; diff --git a/src/core/server/saved_objects/service/lib/search_dsl/sorting_params.ts b/src/core/server/saved_objects/service/lib/search_dsl/sorting_params.ts index 030219b4ba5b1..d2308736b5dc2 100644 --- a/src/core/server/saved_objects/service/lib/search_dsl/sorting_params.ts +++ b/src/core/server/saved_objects/service/lib/search_dsl/sorting_params.ts @@ -8,7 +8,7 @@ import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import Boom from '@hapi/boom'; -import { getProperty, IndexMapping } from '../../../mappings'; +import { getProperty, type IndexMapping } from '@kbn/core-saved-objects-base-server-internal'; const TOP_LEVEL_FIELDS = ['_id', '_score']; diff --git a/src/core/server/saved_objects/service/lib/update_objects_spaces.test.ts b/src/core/server/saved_objects/service/lib/update_objects_spaces.test.ts index dfd1600e6d218..6e6c241965056 100644 --- a/src/core/server/saved_objects/service/lib/update_objects_spaces.test.ts +++ b/src/core/server/saved_objects/service/lib/update_objects_spaces.test.ts @@ -17,12 +17,14 @@ import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-m import { loggerMock } from '@kbn/logging-mocks'; import type { SavedObjectsUpdateObjectsSpacesObject } from '@kbn/core-saved-objects-api-server'; -import { typeRegistryMock } from '../../saved_objects_type_registry.mock'; -import { SavedObjectsSerializer } from '../../serialization'; +import { + SavedObjectsErrorHelpers, + ALL_NAMESPACES_STRING, +} from '@kbn/core-saved-objects-utils-server'; +import { SavedObjectsSerializer } from '@kbn/core-saved-objects-base-server-internal'; +import { typeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks'; import type { UpdateObjectsSpacesParams } from './update_objects_spaces'; import { updateObjectsSpaces } from './update_objects_spaces'; -import { ALL_NAMESPACES_STRING } from './utils'; -import { SavedObjectsErrorHelpers } from './errors'; type SetupParams = Partial< Pick diff --git a/src/core/server/saved_objects/service/lib/update_objects_spaces.ts b/src/core/server/saved_objects/service/lib/update_objects_spaces.ts index a92f9a952af18..4053fcff4a8ea 100644 --- a/src/core/server/saved_objects/service/lib/update_objects_spaces.ts +++ b/src/core/server/saved_objects/service/lib/update_objects_spaces.ts @@ -22,10 +22,15 @@ import type { ISavedObjectTypeRegistry, SavedObjectsRawDocSource, } from '@kbn/core-saved-objects-server'; -import type { IndexMapping } from '../../mappings'; -import type { SavedObjectsSerializer } from '../../serialization'; -import type { DecoratedError } from './errors'; -import { SavedObjectsErrorHelpers } from './errors'; +import { + SavedObjectsErrorHelpers, + ALL_NAMESPACES_STRING, + type DecoratedError, +} from '@kbn/core-saved-objects-utils-server'; +import type { + IndexMapping, + SavedObjectsSerializer, +} from '@kbn/core-saved-objects-base-server-internal'; import { getBulkOperationError, getExpectedVersionProperties, @@ -36,7 +41,6 @@ import { } from './internal_utils'; import { DEFAULT_REFRESH_SETTING } from './repository'; import type { RepositoryEsClient } from './repository_es_client'; -import { ALL_NAMESPACES_STRING } from './utils'; import type { DeleteLegacyUrlAliasesParams } from './legacy_url_aliases'; import { deleteLegacyUrlAliases } from './legacy_url_aliases'; diff --git a/src/core/server/saved_objects/service/saved_objects_client.mock.ts b/src/core/server/saved_objects/service/saved_objects_client.mock.ts index fe5ea92ed0766..55a96ea3cecfc 100644 --- a/src/core/server/saved_objects/service/saved_objects_client.mock.ts +++ b/src/core/server/saved_objects/service/saved_objects_client.mock.ts @@ -7,7 +7,7 @@ */ import type { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; -import { SavedObjectsErrorHelpers } from './lib/errors'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import { savedObjectsPointInTimeFinderMock } from './lib/point_in_time_finder.mock'; const create = () => { diff --git a/src/core/server/saved_objects/service/saved_objects_client.ts b/src/core/server/saved_objects/service/saved_objects_client.ts index c9cfd9e720056..7c2b3a205b76d 100644 --- a/src/core/server/saved_objects/service/saved_objects_client.ts +++ b/src/core/server/saved_objects/service/saved_objects_client.ts @@ -40,7 +40,7 @@ import type { SavedObjectsCreatePointInTimeFinderOptions, SavedObjectsFindOptions, } from '@kbn/core-saved-objects-api-server'; -import { SavedObjectsErrorHelpers } from './lib/errors'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; /** * Core internal implementation of {@link SavedObjectsClientContract} diff --git a/src/core/server/server.ts b/src/core/server/server.ts index 42878ca66e614..82705f2428e5c 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -45,6 +45,10 @@ import { import { MetricsService, opsConfig } from '@kbn/core-metrics-server-internal'; import { CapabilitiesService } from '@kbn/core-capabilities-server-internal'; import type { SavedObjectsServiceStart } from '@kbn/core-saved-objects-server'; +import { + savedObjectsConfig, + savedObjectsMigrationConfig, +} from '@kbn/core-saved-objects-base-server-internal'; import { CoreApp } from './core_app'; import { I18nService } from './i18n'; import { HttpResourcesService } from './http_resources'; @@ -53,9 +57,8 @@ import { UiSettingsService } from './ui_settings'; import { PluginsService, config as pluginsConfig } from './plugins'; import { SavedObjectsService } from './saved_objects'; // do not try to shorten the import to `./status`, it will break server test mocking -import { StatusService } from './status/status_service'; -import { savedObjectsConfig, savedObjectsMigrationConfig } from './saved_objects'; +import { StatusService } from './status/status_service'; import { config as uiSettingsConfig } from './ui_settings'; import { config as statusConfig } from './status'; import { config as i18nConfig } from './i18n'; diff --git a/src/core/server/ui_settings/create_or_upgrade_saved_config/create_or_upgrade_saved_config.test.ts b/src/core/server/ui_settings/create_or_upgrade_saved_config/create_or_upgrade_saved_config.test.ts index c5a9c9729b78a..6102ff6f7b1be 100644 --- a/src/core/server/ui_settings/create_or_upgrade_saved_config/create_or_upgrade_saved_config.test.ts +++ b/src/core/server/ui_settings/create_or_upgrade_saved_config/create_or_upgrade_saved_config.test.ts @@ -10,7 +10,7 @@ import { mockTransform, mockGetUpgradeableConfig, } from './create_or_upgrade_saved_config.test.mock'; -import { SavedObjectsErrorHelpers } from '../../saved_objects'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import { savedObjectsClientMock } from '../../saved_objects/service/saved_objects_client.mock'; import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; diff --git a/src/core/server/ui_settings/create_or_upgrade_saved_config/create_or_upgrade_saved_config.ts b/src/core/server/ui_settings/create_or_upgrade_saved_config/create_or_upgrade_saved_config.ts index def1b58784174..e453c9cf46f31 100644 --- a/src/core/server/ui_settings/create_or_upgrade_saved_config/create_or_upgrade_saved_config.ts +++ b/src/core/server/ui_settings/create_or_upgrade_saved_config/create_or_upgrade_saved_config.ts @@ -11,7 +11,7 @@ import { defaults } from 'lodash'; import type { Logger, LogMeta } from '@kbn/logging'; import { asyncForEach } from '@kbn/std'; import type { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; -import { SavedObjectsErrorHelpers } from '../../saved_objects'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import { getUpgradeableConfig } from './get_upgradeable_config'; import { transforms } from '../saved_objects'; diff --git a/src/core/server/ui_settings/routes/delete.ts b/src/core/server/ui_settings/routes/delete.ts index 705a5319c1cf5..4147358d4e1ee 100644 --- a/src/core/server/ui_settings/routes/delete.ts +++ b/src/core/server/ui_settings/routes/delete.ts @@ -8,7 +8,7 @@ import { schema } from '@kbn/config-schema'; -import { SavedObjectsErrorHelpers } from '../../saved_objects'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import type { InternalUiSettingsRouter } from '../internal_types'; import { CannotOverrideError } from '../ui_settings_errors'; diff --git a/src/core/server/ui_settings/routes/get.ts b/src/core/server/ui_settings/routes/get.ts index c940c2e1fe71e..2603526c37503 100644 --- a/src/core/server/ui_settings/routes/get.ts +++ b/src/core/server/ui_settings/routes/get.ts @@ -6,8 +6,8 @@ * Side Public License, v 1. */ +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import type { InternalUiSettingsRouter } from '../internal_types'; -import { SavedObjectsErrorHelpers } from '../../saved_objects'; export function registerGetRoute(router: InternalUiSettingsRouter) { router.get( diff --git a/src/core/server/ui_settings/routes/set.ts b/src/core/server/ui_settings/routes/set.ts index af62fda0144b6..61493be876ad7 100644 --- a/src/core/server/ui_settings/routes/set.ts +++ b/src/core/server/ui_settings/routes/set.ts @@ -8,7 +8,7 @@ import { schema, ValidationError } from '@kbn/config-schema'; -import { SavedObjectsErrorHelpers } from '../../saved_objects'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import type { InternalUiSettingsRouter } from '../internal_types'; import { CannotOverrideError } from '../ui_settings_errors'; diff --git a/src/core/server/ui_settings/routes/set_many.ts b/src/core/server/ui_settings/routes/set_many.ts index fe0ee1a0a721f..3bbe14c4a0076 100644 --- a/src/core/server/ui_settings/routes/set_many.ts +++ b/src/core/server/ui_settings/routes/set_many.ts @@ -8,7 +8,7 @@ import { schema, ValidationError } from '@kbn/config-schema'; -import { SavedObjectsErrorHelpers } from '../../saved_objects'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import type { InternalUiSettingsRouter } from '../internal_types'; import { CannotOverrideError } from '../ui_settings_errors'; diff --git a/src/core/server/ui_settings/saved_objects/transforms.test.ts b/src/core/server/ui_settings/saved_objects/transforms.test.ts index afcd525673aa0..279dfd637b9e2 100644 --- a/src/core/server/ui_settings/saved_objects/transforms.test.ts +++ b/src/core/server/ui_settings/saved_objects/transforms.test.ts @@ -7,7 +7,7 @@ */ import { savedObjectsClientMock } from '../../mocks'; -import { SavedObjectsErrorHelpers } from '../../saved_objects'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import { SavedObject } from '../../types'; import type { UpgradeableConfigAttributes } from '../create_or_upgrade_saved_config'; import { transformDefaultIndex } from './transforms'; diff --git a/src/core/server/ui_settings/saved_objects/transforms.ts b/src/core/server/ui_settings/saved_objects/transforms.ts index cabf14a2e6469..797b895f91556 100644 --- a/src/core/server/ui_settings/saved_objects/transforms.ts +++ b/src/core/server/ui_settings/saved_objects/transforms.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { SavedObjectsErrorHelpers } from '../../saved_objects'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import type { SavedObjectsClientContract } from '../../types'; import type { UpgradeableConfigAttributes } from '../create_or_upgrade_saved_config'; diff --git a/src/core/server/ui_settings/ui_settings_client.ts b/src/core/server/ui_settings/ui_settings_client.ts index 5175af54ffe3e..aa7d344881cf6 100644 --- a/src/core/server/ui_settings/ui_settings_client.ts +++ b/src/core/server/ui_settings/ui_settings_client.ts @@ -8,7 +8,7 @@ import type { Logger } from '@kbn/logging'; import type { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; -import { SavedObjectsErrorHelpers } from '../saved_objects'; +import { SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; import { createOrUpgradeSavedConfig } from './create_or_upgrade_saved_config'; import { UiSettingsParams } from './types'; import { CannotOverrideError } from './ui_settings_errors'; diff --git a/src/plugins/data/public/index.ts b/src/plugins/data/public/index.ts index c26b5a6ad8114..d970287253e3f 100644 --- a/src/plugins/data/public/index.ts +++ b/src/plugins/data/public/index.ts @@ -111,6 +111,7 @@ import { toAbsoluteDates, boundsDescendingRaw, getResponseInspectorStats, + calcAutoIntervalLessThan, // tabify tabifyAggResponse, tabifyGetColumns, @@ -217,6 +218,7 @@ export const search = { termsAggFilter, toAbsoluteDates, boundsDescendingRaw, + calcAutoIntervalLessThan, }, getResponseInspectorStats, tabifyAggResponse, diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/index.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/index.test.ts index c0ce9d5f8804e..435335fe9dd25 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/index.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/index.test.ts @@ -5,33 +5,9 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import type { DataView } from '@kbn/data-plugin/common'; -import type { Panel, Series } from '../../common/types'; -import { convertTSVBtoLensConfiguration } from '.'; - -const dataViewsMap: Record = { - test1: { id: 'test1', title: 'test1', timeFieldName: 'timeField1' } as DataView, - test2: { - id: 'test2', - title: 'test2', - timeFieldName: 'timeField2', - } as DataView, - test3: { id: 'test3', title: 'test3', timeFieldName: 'timeField3' } as DataView, -}; -const getDataview = (id: string): DataView | undefined => dataViewsMap[id]; -jest.mock('../services', () => { - return { - getDataViewsStart: jest.fn(() => { - return { - getDefault: jest.fn(() => { - return { id: '12345', title: 'default', timeFieldName: '@timestamp' }; - }), - get: getDataview, - }; - }), - }; -}); +import type { Panel } from '../../common/types'; +import { convertTSVBtoLensConfiguration } from '.'; const model = { axis_position: 'left', @@ -61,7 +37,7 @@ const model = { } as Panel; describe('convertTSVBtoLensConfiguration', () => { - test('should return null for a non timeseries chart', async () => { + test('should return null for a not supported chart', async () => { const metricModel = { ...model, type: 'metric', @@ -78,279 +54,4 @@ describe('convertTSVBtoLensConfiguration', () => { const triggerOptions = await convertTSVBtoLensConfiguration(stringIndexPatternModel); expect(triggerOptions).toBeNull(); }); - - test('should return null for a non supported aggregation', async () => { - const nonSupportedAggModel = { - ...model, - series: [ - { - ...model.series[0], - metrics: [ - { - type: 'std_deviation', - }, - ] as Series['metrics'], - }, - ], - }; - const triggerOptions = await convertTSVBtoLensConfiguration(nonSupportedAggModel); - expect(triggerOptions).toBeNull(); - }); - - test('should return options for a supported aggregation', async () => { - const triggerOptions = await convertTSVBtoLensConfiguration(model); - expect(triggerOptions).toStrictEqual({ - configuration: { - extents: { yLeftExtent: { mode: 'full' }, yRightExtent: { mode: 'full' } }, - fill: '0', - gridLinesVisibility: { x: false, yLeft: false, yRight: false }, - legend: { - isVisible: false, - maxLines: 1, - position: 'right', - shouldTruncate: false, - showSingleSeries: false, - }, - }, - type: 'lnsXY', - layers: { - '0': { - axisPosition: 'left', - chartType: 'line', - collapseFn: undefined, - indexPatternId: 'test2', - metrics: [ - { - agg: 'count', - color: '#000000', - fieldName: 'document', - isFullReference: false, - params: {}, - }, - ], - palette: { - name: 'default', - type: 'palette', - }, - splitWithDateHistogram: false, - timeFieldName: 'timeField2', - timeInterval: 'auto', - dropPartialBuckets: false, - }, - }, - }); - }); - - test('should return area for timeseries line chart with fill > 0', async () => { - const modelWithFill = { - ...model, - series: [ - { - ...model.series[0], - fill: '0.3', - stacked: 'none', - }, - ], - }; - const triggerOptions = await convertTSVBtoLensConfiguration(modelWithFill); - expect(triggerOptions?.layers[0].chartType).toBe('area'); - }); - - test('should return timeShift in the params if it is provided', async () => { - const modelWithFill = { - ...model, - series: [ - { - ...model.series[0], - offset_time: '1h', - }, - ], - }; - const triggerOptions = await convertTSVBtoLensConfiguration(modelWithFill); - expect(triggerOptions?.layers[0]?.metrics?.[0]?.params?.shift).toBe('1h'); - }); - - test('should return filter in the params if it is provided', async () => { - const modelWithFill = { - ...model, - series: [ - { - ...model.series[0], - filter: { - language: 'kuery', - query: 'test', - }, - }, - ], - }; - const triggerOptions = await convertTSVBtoLensConfiguration(modelWithFill); - expect(triggerOptions?.layers[0]?.metrics?.[0]?.params?.kql).toBe('test'); - }); - - test('should return splitFilters information if the chart is broken down by filters', async () => { - const modelWithSplitFilters = { - ...model, - series: [ - { - ...model.series[0], - split_mode: 'filters', - split_filters: [ - { - color: 'rgba(188,0,85,1)', - filter: { - language: 'kuery', - query: '', - }, - id: '89afac60-7d2b-11ec-917c-c18cd38d60b5', - }, - ], - }, - ], - }; - const triggerOptions = await convertTSVBtoLensConfiguration(modelWithSplitFilters); - expect(triggerOptions?.layers[0]?.splitFilters).toStrictEqual([ - { - color: 'rgba(188,0,85,1)', - filter: { - language: 'kuery', - query: '', - }, - id: '89afac60-7d2b-11ec-917c-c18cd38d60b5', - }, - ]); - }); - - test('should return termsParams information if the chart is broken down by terms including series agg collapse fn', async () => { - const modelWithTerms = { - ...model, - series: [ - { - ...model.series[0], - metrics: [ - ...model.series[0].metrics, - { - type: 'series_agg', - function: 'sum', - }, - ], - split_mode: 'terms', - terms_size: 6, - terms_direction: 'desc', - terms_order_by: '_key', - }, - ] as unknown as Series[], - }; - const triggerOptions = await convertTSVBtoLensConfiguration(modelWithTerms); - expect(triggerOptions?.layers[0]?.collapseFn).toStrictEqual('sum'); - expect(triggerOptions?.layers[0]?.termsParams).toStrictEqual({ - size: 6, - otherBucket: false, - orderDirection: 'desc', - orderBy: { type: 'alphabetical' }, - includeIsRegex: false, - excludeIsRegex: false, - parentFormat: { - id: 'terms', - }, - }); - }); - - test('should return include exclude information if the chart is broken down by terms', async () => { - const modelWithTerms = { - ...model, - series: [ - { - ...model.series[0], - split_mode: 'terms', - terms_size: 6, - terms_direction: 'desc', - terms_order_by: '_key', - terms_include: 't.*', - }, - ] as unknown as Series[], - }; - const triggerOptions = await convertTSVBtoLensConfiguration(modelWithTerms); - expect(triggerOptions?.layers[0]?.termsParams).toStrictEqual({ - size: 6, - otherBucket: false, - orderDirection: 'desc', - orderBy: { type: 'alphabetical' }, - includeIsRegex: true, - include: ['t.*'], - excludeIsRegex: false, - parentFormat: { - id: 'terms', - }, - }); - }); - - test('should return custom time interval if it is given', async () => { - const modelWithTerms = { - ...model, - interval: '1h', - }; - const triggerOptions = await convertTSVBtoLensConfiguration(modelWithTerms); - expect(triggerOptions?.layers[0]?.timeInterval).toBe('1h'); - }); - - test('should return dropPartialbuckets if enabled', async () => { - const modelWithDropBuckets = { - ...model, - drop_last_bucket: 1, - }; - const triggerOptions = await convertTSVBtoLensConfiguration(modelWithDropBuckets); - expect(triggerOptions?.layers[0]?.dropPartialBuckets).toBe(true); - }); - - test('should return the correct chart configuration', async () => { - const modelWithConfig = { - ...model, - show_legend: 1, - legend_position: 'bottom', - truncate_legend: 0, - show_grid: 1, - series: [{ ...model.series[0], fill: '0.3', separate_axis: 1, axis_position: 'right' }], - }; - const triggerOptions = await convertTSVBtoLensConfiguration(modelWithConfig); - expect(triggerOptions).toStrictEqual({ - configuration: { - extents: { yLeftExtent: { mode: 'full' }, yRightExtent: { mode: 'full' } }, - fill: '0.3', - gridLinesVisibility: { x: true, yLeft: true, yRight: true }, - legend: { - isVisible: true, - maxLines: 1, - position: 'bottom', - shouldTruncate: false, - showSingleSeries: true, - }, - }, - type: 'lnsXY', - layers: { - '0': { - axisPosition: 'right', - chartType: 'area_stacked', - collapseFn: undefined, - indexPatternId: 'test2', - metrics: [ - { - agg: 'count', - color: '#000000', - fieldName: 'document', - isFullReference: false, - params: {}, - }, - ], - palette: { - name: 'default', - type: 'palette', - }, - splitWithDateHistogram: false, - timeFieldName: 'timeField2', - timeInterval: 'auto', - dropPartialBuckets: false, - }, - }, - }); - }); }); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/index.ts index 071001381f0f1..08806f42e1976 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/index.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import { TimeRange } from '@kbn/data-plugin/common'; import type { Panel } from '../../common/types'; import { PANEL_TYPES } from '../../common/enums'; import { ConvertTsvbToLensVisualization } from './types'; @@ -18,6 +19,10 @@ const getConvertFnByType = ( const { convertToLens } = await import('./timeseries'); return convertToLens; }, + [PANEL_TYPES.TOP_N]: async () => { + const { convertToLens } = await import('./top_n'); + return convertToLens; + }, }; return convertionFns[type]?.(); @@ -28,12 +33,17 @@ const getConvertFnByType = ( * Returns the Lens model, only if it is supported. If not, it returns null. * In case of null, the menu item is disabled and the user can't navigate to Lens. */ -export const convertTSVBtoLensConfiguration = async (model: Panel) => { - // Disables the option for not timeseries charts, for the string mode and for series with annotations +export const convertTSVBtoLensConfiguration = async (model: Panel, timeRange?: TimeRange) => { + // Disables the option for not supported charts, for the string mode and for series with annotations if (!model.use_kibana_indexes || (model.annotations && model.annotations.length > 0)) { return null; } + // Disables if model is invalid + if (model.isModelInvalid) { + return null; + } + const convertFn = await getConvertFnByType(model.type); - return (await convertFn?.(model)) ?? null; + return (await convertFn?.(model, timeRange)) ?? null; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/layers/get_layer.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/layers/get_layer.ts index 8483c6f2c3191..de4c61e54837e 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/layers/get_layer.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/layers/get_layer.ts @@ -41,18 +41,21 @@ export const getLayerConfiguration = ( model: Panel, series: VisSeries, splitFields: string[], - timeField?: string, - splitWithDateHistogram?: boolean + xFieldName?: string, + xMode?: string, + splitWithDateHistogram?: boolean, + window?: string ): VisualizeEditorLayersContext => { const layer = model.series[layerIdx]; const palette = layer.palette as PaletteOutput; const splitFilters = convertSplitFilters(layer); const { metrics: metricsArray, seriesAgg } = series; const filter = convertFilter(layer); - const metrics = convertMetrics(layer, metricsArray, filter); + const metrics = convertMetrics(layer, metricsArray, filter, window); return { indexPatternId, - timeFieldName: timeField, + xFieldName, + xMode, chartType, axisPosition: layer.separate_axis ? layer.axis_position : model.axis_position, ...(layer.terms_field && { splitFields }), diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts index a132b861889fa..c341351c66418 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts @@ -7,6 +7,7 @@ */ import type { Query } from '@kbn/es-query'; +import { addTimeRangeToFormula } from '.'; import type { Metric } from '../../../../common/types'; import { SUPPORTED_METRICS } from './supported_metrics'; @@ -14,15 +15,15 @@ const escapeQuotes = (str: string) => { return str?.replace(/'/g, "\\'"); }; -const constructFilterRationFormula = (operation: string, metric?: Query) => { +const constructFilterRationFormula = (operation: string, metric?: Query, window?: string) => { return `${operation}${metric?.language === 'lucene' ? 'lucene' : 'kql'}='${ metric?.query && typeof metric?.query === 'string' ? escapeQuotes(metric?.query) : metric?.query ?? '*' - }')`; + }'${addTimeRangeToFormula(window)})`; }; -export const getFilterRatioFormula = (currentMetric: Metric) => { +export const getFilterRatioFormula = (currentMetric: Metric, window?: string) => { // eslint-disable-next-line @typescript-eslint/naming-convention const { numerator, denominator, metric_agg, field } = currentMetric; let aggregation = SUPPORTED_METRICS.count; @@ -38,16 +39,18 @@ export const getFilterRatioFormula = (currentMetric: Metric) => { if (aggregation.name === 'counter_rate') { const numeratorFormula = constructFilterRationFormula( `${aggregation.name}(max('${field}',`, - numerator + numerator, + window ); const denominatorFormula = constructFilterRationFormula( `${aggregation.name}(max('${field}',`, - denominator + denominator, + window ); return `${numeratorFormula}) / ${denominatorFormula})`; } else { - const numeratorFormula = constructFilterRationFormula(operation, numerator); - const denominatorFormula = constructFilterRationFormula(operation, denominator); + const numeratorFormula = constructFilterRationFormula(operation, numerator, window); + const denominatorFormula = constructFilterRationFormula(operation, denominator, window); return `${numeratorFormula} / ${denominatorFormula}`; } }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/index.ts index 9a79fb804e3ba..08a7599ba3f8d 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/index.ts @@ -13,3 +13,4 @@ export * from './parent_pipeline_formula'; export * from './sibling_pipeline_formula'; export * from './filter_ratio_formula'; export * from './parent_pipeline_series'; +export * from './validate_metrics'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_converter.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_converter.ts index 65427bfa2a268..6ea305fdface3 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_converter.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_converter.ts @@ -27,7 +27,8 @@ export const convertFilter = (series: Series): Filter | void => { const convertMetric = ( series: Series, metric: VisualizeEditorLayersContext['metrics'][number], - filter: Filter | void + filter: Filter | void, + interval?: string ) => ({ ...metric, color: metric.color ?? series.color, @@ -35,11 +36,13 @@ const convertMetric = ( ...metric.params, ...(series.offset_time && { shift: series.offset_time }), ...(filter && filter), + ...(interval && { window: interval }), }, }); export const convertMetrics = ( series: Series, metrics: VisualizeEditorLayersContext['metrics'], - filter: Filter | void -) => metrics.map((metric) => convertMetric(series, metric, filter)); + filter: Filter | void, + interval?: string +) => metrics.map((metric) => convertMetric(series, metric, filter, interval)); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts index 83922a54aa111..b07bcecb7f790 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts @@ -44,7 +44,7 @@ describe('getPercentilesSeries', () => { value: '90', }, ] as Metric['percentiles']; - const config = getPercentilesSeries(percentiles, 'bytes'); + const config = getPercentilesSeries(percentiles, 'everything', '', 'bytes'); expect(config).toStrictEqual([ { agg: 'percentile', @@ -82,7 +82,7 @@ describe('getPercentileRankSeries', () => { test('should return correct config for multiple percentile ranks', () => { const values = ['1', '5', '7'] as Metric['values']; const colors = ['#68BC00', 'rgba(0,63,188,1)', 'rgba(188,38,0,1)'] as Metric['colors']; - const config = getPercentileRankSeries(values, colors, 'day_of_week_i'); + const config = getPercentileRankSeries(values, colors, 'everything', '', 'day_of_week_i'); expect(config).toStrictEqual([ { agg: 'percentile_rank', diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts index fdc7f4ca2f6d0..400adb4571fb7 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts @@ -6,18 +6,28 @@ * Side Public License, v 1. */ +import { utc } from 'moment'; +import { search } from '@kbn/data-plugin/public'; +import dateMath from '@kbn/datemath'; +import { TimeRange, UI_SETTINGS } from '@kbn/data-plugin/common'; +import { getUISettings } from '../../../services'; import type { Metric } from '../../../../common/types'; import { SUPPORTED_METRICS } from './supported_metrics'; import { getFilterRatioFormula } from './filter_ratio_formula'; import { getParentPipelineSeriesFormula } from './parent_pipeline_formula'; import { getSiblingPipelineSeriesFormula } from './sibling_pipeline_formula'; -export const getPercentilesSeries = (percentiles: Metric['percentiles'], fieldName?: string) => { +export const getPercentilesSeries = ( + percentiles: Metric['percentiles'], + splitMode: string, + layerColor: string, + fieldName?: string +) => { return percentiles?.map((percentile) => { return { agg: 'percentile', isFullReference: false, - color: percentile.color, + color: splitMode === 'everything' ? percentile.color : layerColor, fieldName: fieldName ?? 'document', params: { percentile: percentile.value }, }; @@ -27,19 +37,42 @@ export const getPercentilesSeries = (percentiles: Metric['percentiles'], fieldNa export const getPercentileRankSeries = ( values: Metric['values'], colors: Metric['colors'], + splitMode: string, + layerColor: string, fieldName?: string ) => { return values?.map((value, index) => { return { agg: 'percentile_rank', isFullReference: false, - color: colors?.[index], + color: splitMode === 'everything' ? colors?.[index] : layerColor, fieldName: fieldName ?? 'document', params: { value }, }; }); }; +export const getWindow = (interval?: string, timeRange?: TimeRange) => { + let window = interval || '1h'; + + if (timeRange && !interval) { + const { from, to } = timeRange; + const timerange = utc(to).valueOf() - utc(from).valueOf(); + const maxBars = getUISettings().get(UI_SETTINGS.HISTOGRAM_BAR_TARGET); + + const duration = search.aggs.calcAutoIntervalLessThan(maxBars, timerange); + const unit = + dateMath.units.find((u) => { + const value = duration.as(u); + return Number.isInteger(value); + }) || 'ms'; + + window = `${duration.as(unit)}${unit}`; + } + + return window; +}; + export const getTimeScale = (metric: Metric) => { const supportedTimeScales = ['1s', '1m', '1h', '1d']; let timeScale; @@ -60,6 +93,10 @@ export const getFormulaSeries = (script: string) => { ]; }; +export const addTimeRangeToFormula = (window?: string) => { + return window ? `, timeRange='${window}'` : ''; +}; + export const getPipelineAgg = (subFunctionMetric: Metric) => { const pipelineAggMap = SUPPORTED_METRICS[subFunctionMetric.type]; if (!pipelineAggMap) { @@ -71,7 +108,8 @@ export const getPipelineAgg = (subFunctionMetric: Metric) => { export const getFormulaEquivalent = ( currentMetric: Metric, metrics: Metric[], - metaValue?: number + metaValue?: number, + window?: string ) => { const aggregation = SUPPORTED_METRICS[currentMetric.type]?.name; switch (currentMetric.type) { @@ -80,7 +118,7 @@ export const getFormulaEquivalent = ( case 'min_bucket': case 'sum_bucket': case 'positive_only': { - return getSiblingPipelineSeriesFormula(currentMetric.type, currentMetric, metrics); + return getSiblingPipelineSeriesFormula(currentMetric.type, currentMetric, metrics, window); } case 'count': { return `${aggregation}()`; @@ -88,10 +126,12 @@ export const getFormulaEquivalent = ( case 'percentile': { return `${aggregation}(${currentMetric.field}${ metaValue ? `, percentile=${metaValue}` : '' - })`; + }${addTimeRangeToFormula(window)})`; } case 'percentile_rank': { - return `${aggregation}(${currentMetric.field}${metaValue ? `, value=${metaValue}` : ''})`; + return `${aggregation}(${currentMetric.field}${ + metaValue ? `, value=${metaValue}` : '' + }${addTimeRangeToFormula(window)})`; } case 'cumulative_sum': case 'derivative': @@ -110,20 +150,34 @@ export const getFormulaEquivalent = ( subFunctionMetric, pipelineAgg, currentMetric.type, - metaValue + metaValue, + window ); } case 'positive_rate': { - return `${aggregation}(max(${currentMetric.field}))`; + return `${aggregation}(max(${currentMetric.field}${addTimeRangeToFormula(window)}))`; } case 'filter_ratio': { - return getFilterRatioFormula(currentMetric); + return getFilterRatioFormula(currentMetric, window); } case 'static': { return `${currentMetric.value}`; } - default: { + case 'std_deviation': { + if (currentMetric.mode === 'lower') { + return `average(${currentMetric.field}${addTimeRangeToFormula(window)}) - ${ + currentMetric.sigma || 1.5 + } * ${aggregation}(${currentMetric.field}${addTimeRangeToFormula(window)})`; + } + if (currentMetric.mode === 'upper') { + return `average(${currentMetric.field}${addTimeRangeToFormula(window)}) + ${ + currentMetric.sigma || 1.5 + } * ${aggregation}(${currentMetric.field}${addTimeRangeToFormula(window)})`; + } return `${aggregation}(${currentMetric.field})`; } + default: { + return `${aggregation}(${currentMetric.field}${addTimeRangeToFormula(window)})`; + } } }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts index e00fe505df1fd..7d12e77fdb8bc 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts @@ -8,14 +8,15 @@ import type { Metric, MetricType } from '../../../../common/types'; import { SUPPORTED_METRICS } from './supported_metrics'; -import { getFilterRatioFormula } from './filter_ratio_formula'; +import { getFormulaEquivalent } from './metrics_helpers'; export const getParentPipelineSeriesFormula = ( metrics: Metric[], subFunctionMetric: Metric, pipelineAgg: string, aggregation: MetricType, - percentileValue?: number + percentileValue?: number, + window?: string ) => { let formula = ''; const aggregationMap = SUPPORTED_METRICS[aggregation]; @@ -42,28 +43,13 @@ export const getParentPipelineSeriesFormula = ( additionalSubFunction.field ?? '' }${additionalFunctionArgs ?? ''})))`; } else { - let additionalFunctionArgs; - if (pipelineAgg === 'percentile' && percentileValue) { - additionalFunctionArgs = `, percentile=${percentileValue}`; - } - if (pipelineAgg === 'percentile_rank' && percentileValue) { - additionalFunctionArgs = `, value=${percentileValue}`; - } - if (pipelineAgg === 'filter_ratio') { - const script = getFilterRatioFormula(subFunctionMetric); - if (!script) { - return null; - } - formula = `${aggregationMap.name}(${script}${additionalFunctionArgs ?? ''})`; - } else if (pipelineAgg === 'counter_rate') { - formula = `${aggregationMap.name}(${pipelineAgg}(max(${subFunctionMetric.field}${ - additionalFunctionArgs ? `${additionalFunctionArgs}` : '' - })))`; - } else { - formula = `${aggregationMap.name}(${pipelineAgg}(${subFunctionMetric.field}${ - additionalFunctionArgs ? `${additionalFunctionArgs}` : '' - }))`; + const subFormula = getFormulaEquivalent(subFunctionMetric, metrics, percentileValue, window); + + if (!subFormula) { + return null; } + + formula = `${aggregationMap.name}(${subFormula})`; } return formula; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.test.ts index 40264b89491b7..db8faccf5976f 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.test.ts @@ -91,7 +91,7 @@ describe('getParentPipelineSeries', () => { { field: 'AvgTicketPrice', id: '04558549-f19f-4a87-9923-27df8b81af3e', - type: 'std_deviation', + type: 'sum_of_squares_bucket', }, { field: '04558549-f19f-4a87-9923-27df8b81af3e', diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts index 6a263ca8bb44d..6f0caf3837b5c 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts @@ -17,11 +17,12 @@ export const computeParentSeries = ( currentMetric: Metric, subFunctionMetric: Metric, pipelineAgg: string, - meta?: number + meta?: number, + window?: string ) => { const aggregationMap = SUPPORTED_METRICS[aggregation]; if (subFunctionMetric.type === 'filter_ratio') { - const script = getFilterRatioFormula(subFunctionMetric); + const script = getFilterRatioFormula(subFunctionMetric, window); if (!script) { return null; } @@ -49,7 +50,8 @@ export const computeParentSeries = ( export const getParentPipelineSeries = ( aggregation: MetricType, currentMetricIdx: number, - metrics: Metric[] + metrics: Metric[], + window?: string ) => { const currentMetric = metrics[currentMetricIdx]; // percentile value is derived from the field Id. It has the format xxx-xxx-xxx-xxx[percentile] @@ -73,7 +75,8 @@ export const getParentPipelineSeries = ( subFunctionMetric, pipelineAgg, aggregation, - metaValue + metaValue, + window ); if (!formula) { return null; @@ -85,7 +88,8 @@ export const getParentPipelineSeries = ( currentMetric, subFunctionMetric, pipelineAgg, - metaValue + metaValue, + window ); } }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts index b3e141b11e598..4243d6c0dd27c 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts @@ -7,12 +7,14 @@ */ import type { Metric, MetricType } from '../../../../common/types'; +import { getFormulaEquivalent } from './metrics_helpers'; import { SUPPORTED_METRICS } from './supported_metrics'; export const getSiblingPipelineSeriesFormula = ( aggregation: MetricType, currentMetric: Metric, - metrics: Metric[] + metrics: Metric[], + window?: string ) => { const [nestedFieldId, nestedMeta] = currentMetric.field?.split('[') ?? []; const subFunctionMetric = metrics.find((metric) => metric.id === nestedFieldId); @@ -43,18 +45,15 @@ export const getSiblingPipelineSeriesFormula = ( additionalSubFunctionField ?? '' }))${minimumValue})`; } else { - let additionalFunctionArgs; - // handle percentile and percentile_rank const nestedMetaValue = Number(nestedMeta?.replace(']', '')); - if (pipelineAggMap.name === 'percentile' && nestedMetaValue) { - additionalFunctionArgs = `, percentile=${nestedMetaValue}`; - } - if (pipelineAggMap.name === 'percentile_rank' && nestedMetaValue) { - additionalFunctionArgs = `, value=${nestedMetaValue}`; + + const subFormula = getFormulaEquivalent(subFunctionMetric, metrics, nestedMetaValue, window); + + if (!subFormula) { + return null; } - formula += `${pipelineAggMap.name}(${subMetricField ?? ''}${ - additionalFunctionArgs ? `${additionalFunctionArgs}` : '' - })${minimumValue})`; + + formula += `${subFormula}${minimumValue})`; } return formula; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts index 29bf2008e208d..a5a50f5f032cf 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts @@ -6,9 +6,13 @@ * Side Public License, v 1. */ +import { PANEL_TYPES, TIME_RANGE_DATA_MODES } from '../../../../common/enums'; interface AggOptions { name: string; isFullReference: boolean; + isFieldRequired: boolean; + supportedPanelTypes: string[]; + supportedTimeRangeModes: string[]; } // list of supported TSVB aggregation types in Lens @@ -19,85 +23,207 @@ export const SUPPORTED_METRICS: { [key: string]: AggOptions } = { avg: { name: 'average', isFullReference: false, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, cardinality: { name: 'unique_count', isFullReference: false, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, count: { name: 'count', isFullReference: false, + isFieldRequired: false, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, positive_rate: { name: 'counter_rate', isFullReference: true, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, moving_average: { name: 'moving_average', isFullReference: true, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES], + supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE], }, derivative: { name: 'differences', isFullReference: true, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES], + supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE], }, cumulative_sum: { name: 'cumulative_sum', isFullReference: true, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES], + supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE], }, avg_bucket: { name: 'overall_average', isFullReference: true, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES], + supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE], }, max_bucket: { name: 'overall_max', isFullReference: true, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES], + supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE], }, min_bucket: { name: 'overall_min', isFullReference: true, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES], + supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE], }, sum_bucket: { name: 'overall_sum', isFullReference: true, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES], + supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE], }, max: { name: 'max', isFullReference: false, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, min: { name: 'min', isFullReference: false, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, percentile: { name: 'percentile', isFullReference: false, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, percentile_rank: { name: 'percentile_rank', isFullReference: false, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, sum: { name: 'sum', isFullReference: false, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, filter_ratio: { name: 'filter_ratio', isFullReference: false, + isFieldRequired: false, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, top_hit: { name: 'last_value', isFullReference: false, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, math: { name: 'formula', isFullReference: true, + isFieldRequired: false, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, positive_only: { name: 'pick_max', isFullReference: true, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES], + supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE], }, static: { name: 'static_value', isFullReference: true, + isFieldRequired: false, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], + }, + value_count: { + name: 'count', + isFullReference: false, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], + }, + std_deviation: { + name: 'standard_deviation', + isFullReference: false, + isFieldRequired: true, + supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], + supportedTimeRangeModes: [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, + ], }, }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/validate_metrics.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/validate_metrics.ts new file mode 100644 index 0000000000000..adcc2e9a94664 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/validate_metrics.ts @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { Metric } from '../../../../common/types'; +import { SUPPORTED_METRICS } from '.'; + +const isMetricValid = ( + metricType: string, + panelType: string, + field?: string, + timeRangeMode?: string +) => { + const isMetricSupported = SUPPORTED_METRICS[metricType]; + if (!isMetricSupported) { + return false; + } + const isPanelTypeSupported = + SUPPORTED_METRICS[metricType].supportedPanelTypes.includes(panelType); + const isTimeRangeModeSupported = + !timeRangeMode || SUPPORTED_METRICS[metricType].supportedTimeRangeModes.includes(timeRangeMode); + return ( + isPanelTypeSupported && + isTimeRangeModeSupported && + (!SUPPORTED_METRICS[metricType].isFieldRequired || field) + ); +}; + +export const isValidMetrics = (metrics: Metric[], panelType: string, timeRangeMode?: string) => { + return metrics.every((metric) => { + const isMetricAggValid = + metric.type !== 'filter_ratio' || + isMetricValid(metric.metric_agg || 'count', panelType, metric.field, timeRangeMode); + return ( + metric.type === 'series_agg' || + (isMetricValid(metric.type, panelType, metric.field, timeRangeMode) && isMetricAggValid) + ); + }); +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.test.ts index aeb401e86dd01..80b7ba29b24c7 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.test.ts @@ -5,6 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ + import type { Metric } from '../../../../common/types'; import { getSeries } from './get_series'; @@ -17,7 +18,7 @@ describe('getSeries', () => { field: 'day_of_week_i', }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'average', @@ -44,7 +45,7 @@ describe('getSeries', () => { }, }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'formula', @@ -71,7 +72,7 @@ describe('getSeries', () => { field: '123456', }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'formula', @@ -97,7 +98,7 @@ describe('getSeries', () => { field: '123456', }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'formula', @@ -122,7 +123,7 @@ describe('getSeries', () => { field: '123456', }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'cumulative_sum', @@ -147,7 +148,7 @@ describe('getSeries', () => { field: '123456', }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'formula', @@ -174,7 +175,7 @@ describe('getSeries', () => { unit: '1m', }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'differences', @@ -202,7 +203,7 @@ describe('getSeries', () => { window: 6, }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'moving_average', @@ -246,7 +247,7 @@ describe('getSeries', () => { window: 6, }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'formula', @@ -293,7 +294,7 @@ describe('getSeries', () => { ], }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'percentile', @@ -335,7 +336,7 @@ describe('getSeries', () => { colors: ['rgba(211,96,134,1)', 'rgba(155,33,230,1)', '#68BC00'], }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'percentile_rank', @@ -377,7 +378,7 @@ describe('getSeries', () => { order_by: 'timestamp', }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'last_value', @@ -405,7 +406,7 @@ describe('getSeries', () => { function: 'mean', }, ] as Metric[]; - const config = getSeries(metric, 1)!; + const config = getSeries(metric, 1, 'everything', '')!; expect(config).toStrictEqual({ metrics: [ { @@ -430,7 +431,7 @@ describe('getSeries', () => { size: 2, }, ] as Metric[]; - const config = getSeries(metric, 1); + const config = getSeries(metric, 1, 'everything', ''); expect(config).toBeNull(); }); @@ -442,7 +443,7 @@ describe('getSeries', () => { value: '10', }, ] as Metric[]; - const config = getSeries(metric, 1); + const config = getSeries(metric, 1, 'everything', ''); expect(config).toBeNull(); }); @@ -454,7 +455,7 @@ describe('getSeries', () => { value: '10', }, ] as Metric[]; - const config = getSeries(metric, 2)!.metrics; + const config = getSeries(metric, 2, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'static_value', @@ -521,7 +522,7 @@ describe('getSeries', () => { ], }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'formula', @@ -572,7 +573,7 @@ describe('getSeries', () => { ], }, ] as Metric[]; - const config = getSeries(metric, 1)!.metrics; + const config = getSeries(metric, 1, 'everything', '')!.metrics; expect(config).toStrictEqual([ { agg: 'formula', diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts index 0db270b465719..a5c4bbfbc548d 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts @@ -28,7 +28,13 @@ export interface VisSeries { seriesAgg?: string; } -export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): VisSeries | null => { +export const getSeries = ( + initialMetrics: Metric[], + totalSeriesNum: number, + splitMode: string, + layerColor: string, + window?: string +): VisSeries | null => { const { metrics, seriesAgg } = getSeriesAgg(initialMetrics); const metricIdx = metrics.length - 1; const aggregation = metrics[metricIdx].type; @@ -44,6 +50,8 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis if (percentiles?.length) { const percentilesSeries = getPercentilesSeries( percentiles, + splitMode, + layerColor, fieldName ) as VisualizeEditorLayersContext['metrics']; metricsArray = [...metricsArray, ...percentilesSeries]; @@ -57,6 +65,8 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis const percentileRanksSeries = getPercentileRankSeries( values, colors, + splitMode, + layerColor, fieldName ) as VisualizeEditorLayersContext['metrics']; metricsArray = [...metricsArray, ...percentileRanksSeries]; @@ -92,12 +102,17 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis const [_, meta] = variable?.field?.split('[') ?? []; const metaValue = Number(meta?.replace(']', '')); if (!metaValue) return; - const script = getFormulaEquivalent(currentMetric, layerMetricsArray, metaValue); + const script = getFormulaEquivalent( + currentMetric, + layerMetricsArray, + metaValue, + window + ); if (!script) return; finalScript = finalScript?.replace(`params.${variable.name}`, script); }); } else { - const script = getFormulaEquivalent(currentMetric, layerMetricsArray); + const script = getFormulaEquivalent(currentMetric, layerMetricsArray, undefined, window); if (!script) return null; const variable = variables.find((v) => v.field === currentMetric.id); finalScript = finalScript?.replaceAll(`params.${variable?.name}`, script); @@ -113,7 +128,8 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis metricsArray = getParentPipelineSeries( aggregation, metricIdx, - metrics + metrics, + window ) as VisualizeEditorLayersContext['metrics']; break; } @@ -137,7 +153,8 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis subFunctionMetric, pipelineAgg, aggregation, - metaValue + metaValue, + window ); if (!formula) return null; metricsArray = getFormulaSeries(formula); @@ -146,7 +163,9 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis aggregation, metrics[metricIdx], subFunctionMetric, - pipelineAgg + pipelineAgg, + undefined, + window ); if (!series) return null; metricsArray = series; @@ -154,7 +173,12 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis break; } case 'positive_only': { - const formula = getSiblingPipelineSeriesFormula(aggregation, metrics[metricIdx], metrics); + const formula = getSiblingPipelineSeriesFormula( + aggregation, + metrics[metricIdx], + metrics, + window + ); if (!formula) { return null; } @@ -165,7 +189,12 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis case 'max_bucket': case 'min_bucket': case 'sum_bucket': { - const formula = getSiblingPipelineSeriesFormula(aggregation, metrics[metricIdx], metrics); + const formula = getSiblingPipelineSeriesFormula( + aggregation, + metrics[metricIdx], + metrics, + window + ); if (!formula) { return null; } @@ -173,7 +202,7 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis break; } case 'filter_ratio': { - const formula = getFilterRatioFormula(metrics[metricIdx]); + const formula = getFilterRatioFormula(metrics[metricIdx], window); if (!formula) { return null; } @@ -221,6 +250,25 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis ]; break; } + case 'std_deviation': { + const currentMetric = metrics[metricIdx]; + if (currentMetric.mode === 'upper' || currentMetric.mode === 'lower') { + const script = getFormulaEquivalent(currentMetric, metrics, undefined, window); + if (!script) return null; + metricsArray = getFormulaSeries(script); + break; + } else if (currentMetric.mode === 'band') { + [ + { ...currentMetric, mode: 'upper' }, + { ...currentMetric, mode: 'lower' }, + ].forEach((metric) => { + const script = getFormulaEquivalent(metric, metrics, undefined, window); + if (!script) return null; + metricsArray.push(...getFormulaSeries(script)); + }); + break; + } + } default: { const timeScale = getTimeScale(metrics[metricIdx]); metricsArray = [ diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.test.ts new file mode 100644 index 0000000000000..7593018a22593 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.test.ts @@ -0,0 +1,340 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import type { DataView } from '@kbn/data-plugin/common'; +import type { Panel, Series } from '../../../common/types'; +import { convertToLens } from '.'; + +const dataViewsMap: Record = { + test1: { id: 'test1', title: 'test1', timeFieldName: 'timeField1' } as DataView, + test2: { + id: 'test2', + title: 'test2', + timeFieldName: 'timeField2', + } as DataView, + test3: { id: 'test3', title: 'test3', timeFieldName: 'timeField3' } as DataView, +}; + +const getDataview = (id: string): DataView | undefined => dataViewsMap[id]; +jest.mock('../../services', () => { + return { + getDataViewsStart: jest.fn(() => { + return { + getDefault: jest.fn(() => { + return { id: '12345', title: 'default', timeFieldName: '@timestamp' }; + }), + get: getDataview, + }; + }), + }; +}); + +const model = { + axis_position: 'left', + type: 'timeseries', + index_pattern: { id: 'test2' }, + use_kibana_indexes: true, + series: [ + { + color: '#000000', + chart_type: 'line', + fill: '0', + id: '85147356-c185-4636-9182-d55f3ab2b6fa', + palette: { + name: 'default', + type: 'palette', + }, + split_mode: 'everything', + metrics: [ + { + id: '3fa8b32f-5c38-4813-9361-1f2817ae5b18', + type: 'count', + }, + ], + override_index_pattern: 0, + }, + ], +} as Panel; + +describe('convertToLens for TimeSeries', () => { + test('should return null for a non supported aggregation', async () => { + const nonSupportedAggModel = { + ...model, + series: [ + { + ...model.series[0], + metrics: [ + { + type: 'sum_of_squares_bucket', + }, + ] as Series['metrics'], + }, + ], + }; + const triggerOptions = await convertToLens(nonSupportedAggModel); + expect(triggerOptions).toBeNull(); + }); + + test('should return options for a supported aggregation', async () => { + const triggerOptions = await convertToLens(model); + expect(triggerOptions).toStrictEqual({ + configuration: { + extents: { yLeftExtent: { mode: 'full' }, yRightExtent: { mode: 'full' } }, + fill: '0', + gridLinesVisibility: { x: false, yLeft: false, yRight: false }, + legend: { + isVisible: false, + maxLines: 1, + position: 'right', + shouldTruncate: false, + showSingleSeries: false, + }, + }, + type: 'lnsXY', + layers: { + '0': { + axisPosition: 'left', + chartType: 'line', + collapseFn: undefined, + indexPatternId: 'test2', + metrics: [ + { + agg: 'count', + color: '#000000', + fieldName: 'document', + isFullReference: false, + params: {}, + }, + ], + palette: { + name: 'default', + type: 'palette', + }, + splitWithDateHistogram: false, + xFieldName: 'timeField2', + xMode: 'date_histogram', + timeInterval: 'auto', + dropPartialBuckets: false, + }, + }, + }); + }); + + test('should return area for timeseries line chart with fill > 0', async () => { + const modelWithFill = { + ...model, + series: [ + { + ...model.series[0], + fill: '0.3', + stacked: 'none', + }, + ], + }; + const triggerOptions = await convertToLens(modelWithFill); + expect(triggerOptions?.layers[0].chartType).toBe('area'); + }); + + test('should return timeShift in the params if it is provided', async () => { + const modelWithFill = { + ...model, + series: [ + { + ...model.series[0], + offset_time: '1h', + }, + ], + }; + const triggerOptions = await convertToLens(modelWithFill); + expect(triggerOptions?.layers[0]?.metrics?.[0]?.params?.shift).toBe('1h'); + }); + + test('should return filter in the params if it is provided', async () => { + const modelWithFill = { + ...model, + series: [ + { + ...model.series[0], + filter: { + language: 'kuery', + query: 'test', + }, + }, + ], + }; + const triggerOptions = await convertToLens(modelWithFill); + expect(triggerOptions?.layers[0]?.metrics?.[0]?.params?.kql).toBe('test'); + }); + + test('should return splitFilters information if the chart is broken down by filters', async () => { + const modelWithSplitFilters = { + ...model, + series: [ + { + ...model.series[0], + split_mode: 'filters', + split_filters: [ + { + color: 'rgba(188,0,85,1)', + filter: { + language: 'kuery', + query: '', + }, + id: '89afac60-7d2b-11ec-917c-c18cd38d60b5', + }, + ], + }, + ], + }; + const triggerOptions = await convertToLens(modelWithSplitFilters); + expect(triggerOptions?.layers[0]?.splitFilters).toStrictEqual([ + { + color: 'rgba(188,0,85,1)', + filter: { + language: 'kuery', + query: '', + }, + id: '89afac60-7d2b-11ec-917c-c18cd38d60b5', + }, + ]); + }); + + test('should return termsParams information if the chart is broken down by terms including series agg collapse fn', async () => { + const modelWithTerms = { + ...model, + series: [ + { + ...model.series[0], + metrics: [ + ...model.series[0].metrics, + { + type: 'series_agg', + function: 'sum', + }, + ], + split_mode: 'terms', + terms_size: 6, + terms_direction: 'desc', + terms_order_by: '_key', + }, + ] as unknown as Series[], + }; + const triggerOptions = await convertToLens(modelWithTerms); + expect(triggerOptions?.layers[0]?.collapseFn).toStrictEqual('sum'); + expect(triggerOptions?.layers[0]?.termsParams).toStrictEqual({ + size: 6, + otherBucket: false, + orderDirection: 'desc', + orderBy: { type: 'alphabetical' }, + includeIsRegex: false, + excludeIsRegex: false, + parentFormat: { + id: 'terms', + }, + }); + }); + + test('should return include exclude information if the chart is broken down by terms', async () => { + const modelWithTerms = { + ...model, + series: [ + { + ...model.series[0], + split_mode: 'terms', + terms_size: 6, + terms_direction: 'desc', + terms_order_by: '_key', + terms_include: 't.*', + }, + ] as unknown as Series[], + }; + const triggerOptions = await convertToLens(modelWithTerms); + expect(triggerOptions?.layers[0]?.termsParams).toStrictEqual({ + size: 6, + otherBucket: false, + orderDirection: 'desc', + orderBy: { type: 'alphabetical' }, + includeIsRegex: true, + include: ['t.*'], + excludeIsRegex: false, + parentFormat: { + id: 'terms', + }, + }); + }); + + test('should return custom time interval if it is given', async () => { + const modelWithTerms = { + ...model, + interval: '1h', + }; + const triggerOptions = await convertToLens(modelWithTerms); + expect(triggerOptions?.layers[0]?.timeInterval).toBe('1h'); + }); + + test('should return dropPartialbuckets if enabled', async () => { + const modelWithDropBuckets = { + ...model, + drop_last_bucket: 1, + }; + const triggerOptions = await convertToLens(modelWithDropBuckets); + expect(triggerOptions?.layers[0]?.dropPartialBuckets).toBe(true); + }); + + test('should return the correct chart configuration', async () => { + const modelWithConfig = { + ...model, + show_legend: 1, + legend_position: 'bottom', + truncate_legend: 0, + show_grid: 1, + series: [{ ...model.series[0], fill: '0.3', separate_axis: 1, axis_position: 'right' }], + }; + const triggerOptions = await convertToLens(modelWithConfig); + expect(triggerOptions).toStrictEqual({ + configuration: { + extents: { yLeftExtent: { mode: 'full' }, yRightExtent: { mode: 'full' } }, + fill: '0.3', + gridLinesVisibility: { x: true, yLeft: true, yRight: true }, + legend: { + isVisible: true, + maxLines: 1, + position: 'bottom', + shouldTruncate: false, + showSingleSeries: true, + }, + }, + type: 'lnsXY', + layers: { + '0': { + axisPosition: 'right', + chartType: 'area_stacked', + collapseFn: undefined, + indexPatternId: 'test2', + metrics: [ + { + agg: 'count', + color: '#000000', + fieldName: 'document', + isFullReference: false, + params: {}, + }, + ], + palette: { + name: 'default', + type: 'palette', + }, + splitWithDateHistogram: false, + xFieldName: 'timeField2', + xMode: 'date_histogram', + timeInterval: 'auto', + dropPartialBuckets: false, + }, + }, + }); + }); +}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts index 2996ad19c42d9..1aa81b950a28c 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts @@ -7,6 +7,7 @@ */ import { VisualizeEditorLayersContext } from '@kbn/visualizations-plugin/public'; +import { PANEL_TYPES } from '../../../common/enums'; import { getDataViewsStart } from '../../services'; import { getDataSourceInfo } from '../lib/datasource'; import { getSeries } from '../lib/series'; @@ -15,6 +16,7 @@ import { ConvertTsvbToLensVisualization } from '../types'; import { convertChartType, getYExtents } from '../lib/xy'; import { getLayerConfiguration } from '../lib/layers'; import { isSplitWithDateHistogram } from '../lib/split_chart'; +import { isValidMetrics } from '../lib/metrics'; export const convertToLens: ConvertTsvbToLensVisualization = async (model) => { const layersConfiguration: { [key: string]: VisualizeEditorLayersContext } = {}; @@ -30,6 +32,10 @@ export const convertToLens: ConvertTsvbToLensVisualization = async (model) => { continue; } + if (!isValidMetrics(layer.metrics, PANEL_TYPES.TIMESERIES)) { + return null; + } + const { indexPatternId, timeField } = await getDataSourceInfo( model.index_pattern, model.time_field, @@ -39,7 +45,7 @@ export const convertToLens: ConvertTsvbToLensVisualization = async (model) => { ); // handle multiple metrics - const series = getSeries(layer.metrics, seriesNum); + const series = getSeries(layer.metrics, seriesNum, layer.split_mode, layer.color); if (!series || !series.metrics) { return null; } @@ -68,6 +74,7 @@ export const convertToLens: ConvertTsvbToLensVisualization = async (model) => { series, splitFields, timeField, + 'date_histogram', splitWithDateHistogram ); } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.test.ts new file mode 100644 index 0000000000000..1f408bf3dfa89 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.test.ts @@ -0,0 +1,329 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import type { DataView } from '@kbn/data-plugin/common'; +import type { Panel, Series } from '../../../common/types'; +import { convertToLens } from '.'; + +const dataViewsMap: Record = { + test1: { id: 'test1', title: 'test1', timeFieldName: 'timeField1' } as DataView, + test2: { + id: 'test2', + title: 'test2', + timeFieldName: 'timeField2', + } as DataView, + test3: { id: 'test3', title: 'test3', timeFieldName: 'timeField3' } as DataView, +}; + +const getDataview = (id: string): DataView | undefined => dataViewsMap[id]; +jest.mock('../../services', () => { + return { + getDataViewsStart: jest.fn(() => { + return { + getDefault: jest.fn(() => { + return { id: '12345', title: 'default', timeFieldName: '@timestamp' }; + }), + get: getDataview, + }; + }), + }; +}); + +const model = { + axis_position: 'left', + type: 'timeseries', + index_pattern: { id: 'test2' }, + use_kibana_indexes: true, + series: [ + { + color: '#000000', + chart_type: 'line', + fill: '0', + id: '85147356-c185-4636-9182-d55f3ab2b6fa', + palette: { + name: 'default', + type: 'palette', + }, + split_mode: 'everything', + metrics: [ + { + id: '3fa8b32f-5c38-4813-9361-1f2817ae5b18', + type: 'count', + }, + ], + override_index_pattern: 0, + }, + ], +} as Panel; + +describe('convertToLens for Top N', () => { + test('should return null for a non supported aggregation', async () => { + const nonSupportedAggModel = { + ...model, + series: [ + { + ...model.series[0], + metrics: [ + { + type: 'sum_of_squares_bucket', + }, + ] as Series['metrics'], + }, + ], + }; + const triggerOptions = await convertToLens(nonSupportedAggModel); + expect(triggerOptions).toBeNull(); + }); + + test('should return options for a supported aggregation', async () => { + const triggerOptions = await convertToLens(model); + expect(triggerOptions).toStrictEqual({ + configuration: { + fill: '0', + gridLinesVisibility: { x: false, yLeft: false, yRight: false }, + legend: { + isVisible: false, + maxLines: 1, + position: 'right', + shouldTruncate: false, + showSingleSeries: false, + }, + valueLabels: true, + tickLabelsVisibility: { x: true, yLeft: false, yRight: false }, + axisTitlesVisibility: { x: false, yLeft: false, yRight: false }, + }, + type: 'lnsXY', + layers: { + '0': { + axisPosition: 'left', + chartType: 'bar_horizontal', + collapseFn: undefined, + indexPatternId: 'test2', + metrics: [ + { + agg: 'count', + color: '#000000', + fieldName: 'document', + isFullReference: false, + params: {}, + }, + ], + palette: { + name: 'default', + type: 'palette', + }, + splitWithDateHistogram: false, + xFieldName: undefined, + xMode: undefined, + timeInterval: 'auto', + dropPartialBuckets: false, + }, + }, + }); + }); + + test('should return timeShift in the params if it is provided', async () => { + const modelWithFill = { + ...model, + series: [ + { + ...model.series[0], + offset_time: '1h', + }, + ], + }; + const triggerOptions = await convertToLens(modelWithFill); + expect(triggerOptions?.layers[0]?.metrics?.[0]?.params?.shift).toBe('1h'); + }); + + test('should return filter in the params if it is provided', async () => { + const modelWithFill = { + ...model, + series: [ + { + ...model.series[0], + filter: { + language: 'kuery', + query: 'test', + }, + }, + ], + }; + const triggerOptions = await convertToLens(modelWithFill); + expect(triggerOptions?.layers[0]?.metrics?.[0]?.params?.kql).toBe('test'); + }); + + test('should return splitFilters information if the chart is broken down by filters', async () => { + const modelWithSplitFilters = { + ...model, + series: [ + { + ...model.series[0], + split_mode: 'filters', + split_filters: [ + { + color: 'rgba(188,0,85,1)', + filter: { + language: 'kuery', + query: '', + }, + id: '89afac60-7d2b-11ec-917c-c18cd38d60b5', + }, + ], + }, + ], + }; + const triggerOptions = await convertToLens(modelWithSplitFilters); + expect(triggerOptions?.layers[0]?.splitFilters).toStrictEqual([ + { + color: 'rgba(188,0,85,1)', + filter: { + language: 'kuery', + query: '', + }, + id: '89afac60-7d2b-11ec-917c-c18cd38d60b5', + }, + ]); + }); + + test('should return termsParams information if the chart is broken down by terms including series agg collapse fn', async () => { + const modelWithTerms = { + ...model, + series: [ + { + ...model.series[0], + metrics: [ + ...model.series[0].metrics, + { + type: 'series_agg', + function: 'sum', + }, + ], + split_mode: 'terms', + terms_size: 6, + terms_direction: 'desc', + terms_order_by: '_key', + }, + ] as unknown as Series[], + }; + const triggerOptions = await convertToLens(modelWithTerms); + expect(triggerOptions?.layers[0]?.collapseFn).toStrictEqual('sum'); + expect(triggerOptions?.layers[0]?.termsParams).toStrictEqual({ + size: 6, + otherBucket: false, + orderDirection: 'desc', + orderBy: { type: 'alphabetical' }, + includeIsRegex: false, + excludeIsRegex: false, + parentFormat: { + id: 'terms', + }, + }); + }); + + test('should return include exclude information if the chart is broken down by terms', async () => { + const modelWithTerms = { + ...model, + series: [ + { + ...model.series[0], + split_mode: 'terms', + terms_size: 6, + terms_direction: 'desc', + terms_order_by: '_key', + terms_include: 't.*', + }, + ] as unknown as Series[], + }; + const triggerOptions = await convertToLens(modelWithTerms); + expect(triggerOptions?.layers[0]?.termsParams).toStrictEqual({ + size: 6, + otherBucket: false, + orderDirection: 'desc', + orderBy: { type: 'alphabetical' }, + includeIsRegex: true, + include: ['t.*'], + excludeIsRegex: false, + parentFormat: { + id: 'terms', + }, + }); + }); + + test('should return custom time interval if it is given', async () => { + const modelWithTerms = { + ...model, + interval: '1h', + }; + const triggerOptions = await convertToLens(modelWithTerms); + expect(triggerOptions?.layers[0]?.timeInterval).toBe('1h'); + }); + + test('should return dropPartialbuckets if enabled', async () => { + const modelWithDropBuckets = { + ...model, + drop_last_bucket: 1, + }; + const triggerOptions = await convertToLens(modelWithDropBuckets); + expect(triggerOptions?.layers[0]?.dropPartialBuckets).toBe(true); + }); + + test('should return the correct chart configuration', async () => { + const modelWithConfig = { + ...model, + show_legend: 1, + legend_position: 'bottom', + truncate_legend: 0, + show_grid: 1, + series: [{ ...model.series[0], fill: '0.3', separate_axis: 1, axis_position: 'right' }], + }; + const triggerOptions = await convertToLens(modelWithConfig); + expect(triggerOptions).toStrictEqual({ + configuration: { + fill: '0.3', + gridLinesVisibility: { x: false, yLeft: false, yRight: false }, + legend: { + isVisible: true, + maxLines: 1, + position: 'bottom', + shouldTruncate: false, + showSingleSeries: true, + }, + valueLabels: true, + tickLabelsVisibility: { x: true, yLeft: false, yRight: false }, + axisTitlesVisibility: { x: false, yLeft: false, yRight: false }, + }, + type: 'lnsXY', + layers: { + '0': { + axisPosition: 'right', + chartType: 'bar_horizontal', + collapseFn: undefined, + indexPatternId: 'test2', + metrics: [ + { + agg: 'count', + color: '#000000', + fieldName: 'document', + isFullReference: false, + params: {}, + }, + ], + palette: { + name: 'default', + type: 'palette', + }, + splitWithDateHistogram: false, + xFieldName: undefined, + xMode: undefined, + timeInterval: 'auto', + dropPartialBuckets: false, + }, + }, + }); + }); +}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts new file mode 100644 index 0000000000000..292a44aaf98d9 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts @@ -0,0 +1,115 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { VisualizeEditorLayersContext } from '@kbn/visualizations-plugin/public'; +import { PANEL_TYPES, TIME_RANGE_DATA_MODES } from '../../../common/enums'; +import { getDataViewsStart } from '../../services'; +import { getDataSourceInfo } from '../lib/datasource'; +import { getSeries } from '../lib/series'; +import { getFieldsForTerms } from '../../../common/fields_utils'; +import { ConvertTsvbToLensVisualization } from '../types'; +import { isSplitWithDateHistogram } from '../lib/split_chart'; +import { getLayerConfiguration } from '../lib/layers'; +import { getWindow, isValidMetrics } from '../lib/metrics'; + +export const convertToLens: ConvertTsvbToLensVisualization = async (model, timeRange) => { + const layersConfiguration: { [key: string]: VisualizeEditorLayersContext } = {}; + + // get the active series number + const seriesNum = model.series.filter((series) => !series.hidden).length; + const dataViews = getDataViewsStart(); + + // handle multiple layers/series + for (let layerIdx = 0; layerIdx < model.series.length; layerIdx++) { + const layer = model.series[layerIdx]; + if (layer.hidden) { + continue; + } + + if (!isValidMetrics(layer.metrics, PANEL_TYPES.TOP_N, layer.time_range_mode)) { + return null; + } + + const { indexPatternId } = await getDataSourceInfo( + model.index_pattern, + model.time_field, + Boolean(layer.override_index_pattern), + layer.series_index_pattern, + dataViews + ); + + const window = + model.time_range_mode === TIME_RANGE_DATA_MODES.LAST_VALUE + ? getWindow(model.interval, timeRange) + : undefined; + + // handle multiple metrics + const series = getSeries(layer.metrics, seriesNum, layer.split_mode, layer.color, window); + if (!series || !series.metrics) { + return null; + } + + const splitFields = getFieldsForTerms(layer.terms_field); + + // in case of terms in a date field, we want to apply the date_histogram + const splitWithDateHistogram = await isSplitWithDateHistogram( + layer, + splitFields, + indexPatternId, + dataViews + ); + + if (splitWithDateHistogram === null) { + return null; + } + + layersConfiguration[layerIdx] = getLayerConfiguration( + indexPatternId, + layerIdx, + 'bar_horizontal', + model, + series, + splitFields, + undefined, + undefined, + splitWithDateHistogram, + window + ); + } + + return { + layers: layersConfiguration, + type: 'lnsXY', + configuration: { + fill: model.series[0].fill ?? 0.3, + legend: { + isVisible: Boolean(model.show_legend), + showSingleSeries: Boolean(model.show_legend), + position: model.legend_position ?? 'right', + shouldTruncate: Boolean(model.truncate_legend), + maxLines: model.max_lines_legend ?? 1, + }, + gridLinesVisibility: { + x: false, + yLeft: false, + yRight: false, + }, + tickLabelsVisibility: { + x: true, + yLeft: false, + yRight: false, + }, + axisTitlesVisibility: { + x: false, + yLeft: false, + yRight: false, + }, + valueLabels: true, + }, + }; +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts index 8c17b9ec6ce57..cf91d9835bac7 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts @@ -6,11 +6,13 @@ * Side Public License, v 1. */ +import { TimeRange } from '@kbn/data-plugin/common'; import { NavigateToLensContext } from '@kbn/visualizations-plugin/public'; import type { Panel } from '../../common/types'; export type ConvertTsvbToLensVisualization = ( - model: Panel + model: Panel, + timeRange?: TimeRange ) => Promise; export interface Filter { diff --git a/src/plugins/vis_types/timeseries/public/metrics_type.ts b/src/plugins/vis_types/timeseries/public/metrics_type.ts index 10658b264c4a3..edd4ac0297b3c 100644 --- a/src/plugins/vis_types/timeseries/public/metrics_type.ts +++ b/src/plugins/vis_types/timeseries/public/metrics_type.ts @@ -9,6 +9,7 @@ import { i18n } from '@kbn/i18n'; import uuid from 'uuid/v4'; import type { DataViewsContract, DataView } from '@kbn/data-views-plugin/public'; +import { TimeRange } from '@kbn/data-plugin/common'; import { Vis, VIS_EVENT_TO_TRIGGER, @@ -168,8 +169,8 @@ export const metricsVisDefinition: VisTypeDefinition< } return []; }, - navigateToLens: async (params?: VisParams) => - params ? await convertTSVBtoLensConfiguration(params as Panel) : null, + navigateToLens: async (params?: VisParams, timeRange?: TimeRange) => + params ? await convertTSVBtoLensConfiguration(params as Panel, timeRange) : null, inspectorAdapters: () => ({ requests: new RequestAdapter(), diff --git a/src/plugins/visualizations/public/vis_types/types.ts b/src/plugins/visualizations/public/vis_types/types.ts index 4267e6a0d8aef..ebcdcf594fdfd 100644 --- a/src/plugins/visualizations/public/vis_types/types.ts +++ b/src/plugins/visualizations/public/vis_types/types.ts @@ -10,6 +10,7 @@ import type { IconType } from '@elastic/eui'; import type { ReactNode } from 'react'; import type { PaletteOutput } from '@kbn/coloring'; import type { Adapters } from '@kbn/inspector-plugin/common'; +import { TimeRange } from '@kbn/data-plugin/common'; import type { Query } from '@kbn/es-query'; import type { AggGroupNames, AggParam, AggGroupName } from '@kbn/data-plugin/public'; import type { DataView } from '@kbn/data-views-plugin/public'; @@ -92,7 +93,8 @@ interface VisualizeEditorMetricContext { export interface VisualizeEditorLayersContext { indexPatternId: string; splitWithDateHistogram?: boolean; - timeFieldName?: string; + xFieldName?: string; + xMode?: string; chartType?: string; axisPosition?: string; termsParams?: Record; @@ -134,7 +136,18 @@ export interface NavigateToLensContext { yLeft: boolean; yRight: boolean; }; - extents: { + tickLabelsVisibility?: { + x: boolean; + yLeft: boolean; + yRight: boolean; + }; + axisTitlesVisibility?: { + x: boolean; + yLeft: boolean; + yRight: boolean; + }; + valueLabels?: boolean; + extents?: { yLeftExtent: AxisExtents; yRightExtent: AxisExtents; }; @@ -173,7 +186,8 @@ export interface VisTypeDefinition { * in order to be displayed in the Lens editor. */ readonly navigateToLens?: ( - params?: VisParams + params?: VisParams, + timeRange?: TimeRange ) => Promise | undefined; /** diff --git a/src/plugins/visualizations/public/visualize_app/components/visualize_top_nav.tsx b/src/plugins/visualizations/public/visualize_app/components/visualize_top_nav.tsx index ca373b31b6020..c80492b45c5cb 100644 --- a/src/plugins/visualizations/public/visualize_app/components/visualize_top_nav.tsx +++ b/src/plugins/visualizations/public/visualize_app/components/visualize_top_nav.tsx @@ -99,12 +99,15 @@ const TopNav = ({ useEffect(() => { const asyncGetTriggerContext = async () => { if (vis.type.navigateToLens) { - const triggerConfig = await vis.type.navigateToLens(vis.params); + const triggerConfig = await vis.type.navigateToLens( + vis.params, + services.data.query.timefilter.timefilter.getAbsoluteTime() + ); setEditInLensConfig(triggerConfig); } }; asyncGetTriggerContext(); - }, [vis.params, vis.type]); + }, [services.data.query.timefilter.timefilter, vis.params, vis.type]); const displayEditInLensItem = Boolean(vis.type.navigateToLens && editInLensConfig); const config = useMemo(() => { diff --git a/x-pack/plugins/actions/server/actions_client.test.ts b/x-pack/plugins/actions/server/actions_client.test.ts index 4576a301a5f2f..44276a604896f 100644 --- a/x-pack/plugins/actions/server/actions_client.test.ts +++ b/x-pack/plugins/actions/server/actions_client.test.ts @@ -45,11 +45,15 @@ import { getOAuthJwtAccessToken } from './builtin_action_types/lib/get_oauth_jwt import { getOAuthClientCredentialsAccessToken } from './builtin_action_types/lib/get_oauth_client_credentials_access_token'; import { OAuthParams } from './routes/get_oauth_access_token'; -jest.mock('@kbn/core/server/saved_objects/service/lib/utils', () => ({ - SavedObjectsUtils: { - generateId: () => 'mock-saved-object-id', - }, -})); +jest.mock('@kbn/core-saved-objects-utils-server', () => { + const actual = jest.requireActual('@kbn/core-saved-objects-utils-server'); + return { + ...actual, + SavedObjectsUtils: { + generateId: () => 'mock-saved-object-id', + }, + }; +}); jest.mock('./lib/track_legacy_rbac_exemption', () => ({ trackLegacyRBACExemption: jest.fn(), diff --git a/x-pack/plugins/actions/server/builtin_action_types/lib/connector_token_client.test.ts b/x-pack/plugins/actions/server/builtin_action_types/lib/connector_token_client.test.ts index dfa307ca3cd91..1aa8bbb3da9a7 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/lib/connector_token_client.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/lib/connector_token_client.test.ts @@ -13,11 +13,15 @@ import { Logger } from '@kbn/core/server'; import { ConnectorToken } from '../../types'; const logger = loggingSystemMock.create().get() as jest.Mocked; -jest.mock('@kbn/core/server/saved_objects/service/lib/utils', () => ({ - SavedObjectsUtils: { - generateId: () => 'mock-saved-object-id', - }, -})); +jest.mock('@kbn/core-saved-objects-utils-server', () => { + const actual = jest.requireActual('@kbn/core-saved-objects-utils-server'); + return { + ...actual, + SavedObjectsUtils: { + generateId: () => 'mock-saved-object-id', + }, + }; +}); const unsecuredSavedObjectsClient = savedObjectsClientMock.create(); const encryptedSavedObjectsClient = encryptedSavedObjectsMock.createClient(); diff --git a/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts index 53f9c59545526..b29d41f183b73 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts @@ -26,11 +26,15 @@ jest.mock('../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation bulkMarkApiKeysForInvalidation: jest.fn(), })); -jest.mock('@kbn/core/server/saved_objects/service/lib/utils', () => ({ - SavedObjectsUtils: { - generateId: () => 'mock-saved-object-id', - }, -})); +jest.mock('@kbn/core-saved-objects-utils-server', () => { + const actual = jest.requireActual('@kbn/core-saved-objects-utils-server'); + return { + ...actual, + SavedObjectsUtils: { + generateId: () => 'mock-saved-object-id', + }, + }; +}); const taskManager = taskManagerMock.createStart(); const ruleTypeRegistry = ruleTypeRegistryMock.create(); diff --git a/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts index 219ee35756f07..9071099ed3aaf 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts @@ -23,11 +23,15 @@ import { auditLoggerMock } from '@kbn/security-plugin/server/audit/mocks'; import { getBeforeSetup, setGlobalDate } from './lib'; import { bulkMarkApiKeysForInvalidation } from '../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation'; -jest.mock('@kbn/core/server/saved_objects/service/lib/utils', () => ({ - SavedObjectsUtils: { - generateId: () => 'mock-saved-object-id', - }, -})); +jest.mock('@kbn/core-saved-objects-utils-server', () => { + const actual = jest.requireActual('@kbn/core-saved-objects-utils-server'); + return { + ...actual, + SavedObjectsUtils: { + generateId: () => 'mock-saved-object-id', + }, + }; +}); jest.mock('../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation', () => ({ bulkMarkApiKeysForInvalidation: jest.fn(), diff --git a/x-pack/plugins/encrypted_saved_objects/server/saved_objects/encrypted_saved_objects_client_wrapper.test.ts b/x-pack/plugins/encrypted_saved_objects/server/saved_objects/encrypted_saved_objects_client_wrapper.test.ts index 724178f9b7088..75dd3fdfe8dce 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/saved_objects/encrypted_saved_objects_client_wrapper.test.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/saved_objects/encrypted_saved_objects_client_wrapper.test.ts @@ -15,11 +15,12 @@ import { EncryptionErrorOperation } from '../crypto/encryption_error'; import { encryptedSavedObjectsServiceMock } from '../crypto/index.mock'; import { EncryptedSavedObjectsClientWrapper } from './encrypted_saved_objects_client_wrapper'; -jest.mock('@kbn/core/server/saved_objects/service/lib/utils', () => { - const { SavedObjectsUtils } = jest.requireActual( - '@kbn/core/server/saved_objects/service/lib/utils' +jest.mock('@kbn/core-saved-objects-utils-server', () => { + const { SavedObjectsUtils, ...actual } = jest.requireActual( + '@kbn/core-saved-objects-utils-server' ); return { + ...actual, SavedObjectsUtils: { namespaceStringToId: SavedObjectsUtils.namespaceStringToId, isRandomId: SavedObjectsUtils.isRandomId, @@ -699,6 +700,7 @@ describe('#bulkUpdate', () => { expectOptionsNamespaceInDescriptor: boolean; expectObjectNamespaceInDescriptor: boolean; } + const doTest = async ({ optionsNamespace, objectNamespace, diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/delete_index_api_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/delete_index_api_logic.test.ts new file mode 100644 index 0000000000000..6eaa5b3e95cf2 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/delete_index_api_logic.test.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { mockHttpValues } from '../../../__mocks__/kea_logic'; + +import { nextTick } from '@kbn/test-jest-helpers'; + +import { deleteIndex } from './delete_index_api_logic'; + +describe('deleteIndexApiLogic', () => { + const { http } = mockHttpValues; + beforeEach(() => { + jest.clearAllMocks(); + }); + describe('deleteIndex', () => { + it('calls correct api', async () => { + const promise = Promise.resolve(); + http.post.mockReturnValue(promise); + const result = deleteIndex({ indexName: 'deleteIndex' }); + await nextTick(); + expect(http.delete).toHaveBeenCalledWith('/internal/enterprise_search/indices/deleteIndex'); + await expect(result).resolves; + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/delete_index_api_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/delete_index_api_logic.ts new file mode 100644 index 0000000000000..ff92e4ecef6bc --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/delete_index_api_logic.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { createApiLogic } from '../../../shared/api_logic/create_api_logic'; +import { HttpLogic } from '../../../shared/http'; + +export interface DeleteIndexApiLogicArgs { + indexName: string; +} + +export const deleteIndex = async ({ indexName }: DeleteIndexApiLogicArgs): Promise => { + const route = `/internal/enterprise_search/indices/${indexName}`; + await HttpLogic.values.http.delete(route); + return; +}; + +export const DeleteIndexApiLogic = createApiLogic(['delete_index_api_logic'], deleteIndex); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/fetch_indices_api_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/fetch_indices_api_logic.test.ts index 13b75e7c534be..42d78b65df449 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/fetch_indices_api_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/fetch_indices_api_logic.test.ts @@ -28,7 +28,12 @@ describe('FetchIndicesApiLogic', () => { expect(http.get).toHaveBeenCalledWith('/internal/enterprise_search/indices', { query: { page: 1, return_hidden_indices: false, search_query: null, size: 20 }, }); - await expect(result).resolves.toEqual({ isInitialRequest: true, result: 'result' }); + await expect(result).resolves.toEqual({ + isInitialRequest: true, + result: 'result', + returnHiddenIndices: false, + searchQuery: undefined, + }); }); it('sets initialRequest to false if page is not the first page', async () => { const promise = Promise.resolve({ result: 'result' }); @@ -41,7 +46,12 @@ describe('FetchIndicesApiLogic', () => { expect(http.get).toHaveBeenCalledWith('/internal/enterprise_search/indices', { query: { page: 2, return_hidden_indices: false, search_query: null, size: 20 }, }); - await expect(result).resolves.toEqual({ isInitialRequest: false, result: 'result' }); + await expect(result).resolves.toEqual({ + isInitialRequest: false, + result: 'result', + returnHiddenIndices: false, + searchQuery: undefined, + }); }); it('sets initialRequest to false if searchQuery is not empty', async () => { const promise = Promise.resolve({ result: 'result' }); @@ -55,7 +65,12 @@ describe('FetchIndicesApiLogic', () => { expect(http.get).toHaveBeenCalledWith('/internal/enterprise_search/indices', { query: { page: 1, return_hidden_indices: false, search_query: 'a', size: 20 }, }); - await expect(result).resolves.toEqual({ isInitialRequest: false, result: 'result' }); + await expect(result).resolves.toEqual({ + isInitialRequest: false, + result: 'result', + returnHiddenIndices: false, + searchQuery: 'a', + }); }); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/fetch_indices_api_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/fetch_indices_api_logic.ts index a1ca3a9c3141f..709c47ed919c0 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/fetch_indices_api_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/fetch_indices_api_logic.ts @@ -38,7 +38,7 @@ export const fetchIndices = async ({ // We need this to determine whether to show the empty state on the indices page const isInitialRequest = meta.page.current === 1 && !searchQuery; - return { ...response, isInitialRequest }; + return { ...response, isInitialRequest, returnHiddenIndices, searchQuery }; }; export const FetchIndicesAPILogic = createApiLogic(['content', 'indices_api_logic'], fetchIndices); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/delete_index_modal.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/delete_index_modal.tsx new file mode 100644 index 0000000000000..99f0e35c352e1 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/delete_index_modal.tsx @@ -0,0 +1,80 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { useActions, useValues } from 'kea'; + +import { EuiConfirmModal } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import { IndicesLogic } from './indices_logic'; + +export const DeleteIndexModal: React.FC = () => { + const { closeDeleteModal, deleteIndex } = useActions(IndicesLogic); + const { deleteModalIndexName: indexName, isDeleteModalVisible } = useValues(IndicesLogic); + return isDeleteModalVisible ? ( + { + closeDeleteModal(); + }} + onConfirm={() => { + deleteIndex({ indexName }); + }} + cancelButtonText={i18n.translate( + 'xpack.enterpriseSearch.content.searchIndices.deleteModal.cancelButton.title', + { + defaultMessage: 'Cancel', + } + )} + confirmButtonText={i18n.translate( + 'xpack.enterpriseSearch.content.searchIndices.deleteModal.confirmButton.title', + { + defaultMessage: 'Delete index', + } + )} + defaultFocusedButton="confirm" + buttonColor="danger" + > +

+ {i18n.translate( + 'xpack.enterpriseSearch.content.searchIndices.deleteModal.delete.description', + { + defaultMessage: + 'You are about to delete the index {indexName}. This will also delete any associated connector documents or crawlers.', + values: { + indexName, + }, + } + )} +

+

+ {i18n.translate( + 'xpack.enterpriseSearch.content.searchIndices.deleteModal.searchEngine.description', + { + defaultMessage: + 'Any associated search engines will no longer be able to access any data stored in this index.', + } + )} +

+

+ {i18n.translate( + 'xpack.enterpriseSearch.content.searchIndices.deleteModal.irrevokable.description', + { + defaultMessage: + "You can't recover a deleted index, connector or crawler configuration. Make sure you have appropriate backups.", + } + )} +

+
+ ) : ( + <> + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_logic.test.ts index 36157301d3bae..2574af68ce50c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_logic.test.ts @@ -28,11 +28,14 @@ import { IndicesLogic } from './indices_logic'; const DEFAULT_VALUES = { data: undefined, + deleteModalIndexName: '', hasNoIndices: false, indices: [], + isDeleteModalVisible: false, isFirstRequest: true, isLoading: true, meta: DEFAULT_META, + searchParams: { meta: DEFAULT_META, returnHiddenIndices: false }, status: Status.IDLE, }; @@ -64,11 +67,75 @@ describe('IndicesLogic', () => { current: 3, }, }, + searchParams: { + ...DEFAULT_VALUES.searchParams, + meta: { page: { ...DEFAULT_META.page, current: 3 } }, + }, }); }); }); + describe('openDeleteModal', () => { + it('should set deleteIndexName and set isDeleteModalVisible to true', () => { + IndicesLogic.actions.openDeleteModal('delete'); + expect(IndicesLogic.values).toEqual({ + ...DEFAULT_VALUES, + deleteModalIndexName: 'delete', + isDeleteModalVisible: true, + }); + }); + }); + describe('closeDeleteModal', () => { + it('should set deleteIndexName to empty and set isDeleteModalVisible to false', () => { + IndicesLogic.actions.openDeleteModal('delete'); + IndicesLogic.actions.closeDeleteModal(); + expect(IndicesLogic.values).toEqual(DEFAULT_VALUES); + }); + }); }); describe('reducers', () => { + describe('isFirstRequest', () => { + it('should update to true on setIsFirstRequest', () => { + IndicesLogic.actions.setIsFirstRequest(); + expect(IndicesLogic.values).toEqual({ ...DEFAULT_VALUES, isFirstRequest: true }); + }); + it('should update to false on apiError', () => { + IndicesLogic.actions.setIsFirstRequest(); + IndicesLogic.actions.apiError({} as HttpError); + + expect(IndicesLogic.values).toEqual({ + ...DEFAULT_VALUES, + hasNoIndices: false, + indices: [], + isFirstRequest: false, + isLoading: false, + status: Status.ERROR, + }); + }); + it('should update to false on apiSuccess', () => { + IndicesLogic.actions.setIsFirstRequest(); + IndicesLogic.actions.apiSuccess({ + indices: [], + isInitialRequest: false, + meta: DEFAULT_VALUES.meta, + returnHiddenIndices: false, + }); + + expect(IndicesLogic.values).toEqual({ + ...DEFAULT_VALUES, + data: { + indices: [], + isInitialRequest: false, + meta: DEFAULT_VALUES.meta, + returnHiddenIndices: false, + }, + hasNoIndices: false, + indices: [], + isFirstRequest: false, + isLoading: false, + status: Status.SUCCESS, + }); + }); + }); describe('meta', () => { it('updates when apiSuccess listener triggered', () => { const newMeta = { @@ -84,18 +151,28 @@ describe('IndicesLogic', () => { indices, isInitialRequest: true, meta: newMeta, + returnHiddenIndices: true, + searchQuery: 'a', }); expect(IndicesLogic.values).toEqual({ + ...DEFAULT_VALUES, data: { indices, isInitialRequest: true, meta: newMeta, + returnHiddenIndices: true, + searchQuery: 'a', }, hasNoIndices: false, indices: elasticsearchViewIndices, isFirstRequest: false, isLoading: false, meta: newMeta, + searchParams: { + meta: newMeta, + returnHiddenIndices: true, + searchQuery: 'a', + }, status: Status.SUCCESS, }); }); @@ -115,18 +192,25 @@ describe('IndicesLogic', () => { indices: [], isInitialRequest: true, meta, + returnHiddenIndices: false, }); expect(IndicesLogic.values).toEqual({ + ...DEFAULT_VALUES, data: { indices: [], isInitialRequest: true, meta, + returnHiddenIndices: false, }, hasNoIndices: true, indices: [], isFirstRequest: false, isLoading: false, meta, + searchParams: { + ...DEFAULT_VALUES.searchParams, + meta, + }, status: Status.SUCCESS, }); }); @@ -144,18 +228,25 @@ describe('IndicesLogic', () => { indices: [], isInitialRequest: false, meta, + returnHiddenIndices: false, }); expect(IndicesLogic.values).toEqual({ + ...DEFAULT_VALUES, data: { indices: [], isInitialRequest: false, meta, + returnHiddenIndices: false, }, hasNoIndices: false, indices: [], isFirstRequest: false, isLoading: false, meta, + searchParams: { + ...DEFAULT_VALUES.searchParams, + meta, + }, status: Status.SUCCESS, }); }); @@ -172,6 +263,21 @@ describe('IndicesLogic', () => { expect(mockFlashMessageHelpers.flashAPIErrors).toHaveBeenCalledTimes(1); expect(mockFlashMessageHelpers.flashAPIErrors).toHaveBeenCalledWith({}); }); + it('calls flashAPIErrors on deleteError', () => { + IndicesLogic.actions.deleteError({} as HttpError); + expect(mockFlashMessageHelpers.flashAPIErrors).toHaveBeenCalledTimes(1); + expect(mockFlashMessageHelpers.flashAPIErrors).toHaveBeenCalledWith({}); + }); + it('calls flashSuccessToast, closeDeleteModal and fetchIndices on deleteSuccess', () => { + IndicesLogic.actions.fetchIndices = jest.fn(); + IndicesLogic.actions.closeDeleteModal = jest.fn(); + IndicesLogic.actions.deleteSuccess(); + expect(mockFlashMessageHelpers.flashSuccessToast).toHaveBeenCalledTimes(1); + expect(IndicesLogic.actions.fetchIndices).toHaveBeenCalledWith( + IndicesLogic.values.searchParams + ); + expect(IndicesLogic.actions.closeDeleteModal).toHaveBeenCalled(); + }); it('calls makeRequest on fetchIndices', async () => { jest.useFakeTimers(); IndicesLogic.actions.makeRequest = jest.fn(); @@ -223,13 +329,16 @@ describe('IndicesLogic', () => { indices: elasticsearchViewIndices, isInitialRequest: true, meta: DEFAULT_META, + returnHiddenIndices: false, }); expect(IndicesLogic.values).toEqual({ + ...DEFAULT_VALUES, data: { indices: elasticsearchViewIndices, isInitialRequest: true, meta: DEFAULT_META, + returnHiddenIndices: false, }, hasNoIndices: false, indices: elasticsearchViewIndices, @@ -256,9 +365,11 @@ describe('IndicesLogic', () => { ], isInitialRequest: true, meta: DEFAULT_META, + returnHiddenIndices: false, }); expect(IndicesLogic.values).toEqual({ + ...DEFAULT_VALUES, data: { indices: [ { @@ -272,6 +383,7 @@ describe('IndicesLogic', () => { ], isInitialRequest: true, meta: DEFAULT_META, + returnHiddenIndices: false, }, hasNoIndices: false, indices: [ @@ -302,9 +414,11 @@ describe('IndicesLogic', () => { ], isInitialRequest: true, meta: DEFAULT_META, + returnHiddenIndices: false, }); expect(IndicesLogic.values).toEqual({ + ...DEFAULT_VALUES, data: { indices: [ { @@ -314,6 +428,7 @@ describe('IndicesLogic', () => { ], isInitialRequest: true, meta: DEFAULT_META, + returnHiddenIndices: false, }, hasNoIndices: false, indices: [ @@ -343,9 +458,11 @@ describe('IndicesLogic', () => { ], isInitialRequest: true, meta: DEFAULT_META, + returnHiddenIndices: false, }); expect(IndicesLogic.values).toEqual({ + ...DEFAULT_VALUES, data: { indices: [ { @@ -355,6 +472,7 @@ describe('IndicesLogic', () => { ], isInitialRequest: true, meta: DEFAULT_META, + returnHiddenIndices: false, }, hasNoIndices: false, indices: [ @@ -385,9 +503,11 @@ describe('IndicesLogic', () => { ], isInitialRequest: true, meta: DEFAULT_META, + returnHiddenIndices: false, }); expect(IndicesLogic.values).toEqual({ + ...DEFAULT_VALUES, data: { indices: [ { @@ -401,6 +521,7 @@ describe('IndicesLogic', () => { ], isInitialRequest: true, meta: DEFAULT_META, + returnHiddenIndices: false, }, hasNoIndices: false, indices: [ diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_logic.ts index 59640a948ddbc..eb09425c1faca 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_logic.ts @@ -7,12 +7,23 @@ import { kea, MakeLogicType } from 'kea'; +import { i18n } from '@kbn/i18n'; + import { Meta } from '../../../../../common/types'; import { HttpError, Status } from '../../../../../common/types/api'; import { ElasticsearchIndexWithIngestion } from '../../../../../common/types/indices'; +import { Actions } from '../../../shared/api_logic/create_api_logic'; import { DEFAULT_META } from '../../../shared/constants'; -import { flashAPIErrors, clearFlashMessages } from '../../../shared/flash_messages'; +import { + flashAPIErrors, + clearFlashMessages, + flashSuccessToast, +} from '../../../shared/flash_messages'; import { updateMetaPageIndex } from '../../../shared/table_pagination'; +import { + DeleteIndexApiLogic, + DeleteIndexApiLogicArgs, +} from '../../api/index/delete_index_api_logic'; import { FetchIndicesAPILogic } from '../../api/index/fetch_indices_api_logic'; import { ElasticsearchViewIndex } from '../../types'; import { indexToViewIndex } from '../../utils/indices'; @@ -23,15 +34,25 @@ export interface IndicesActions { indices, isInitialRequest, meta, + returnHiddenIndices, + searchQuery, }: { indices: ElasticsearchIndexWithIngestion[]; isInitialRequest: boolean; meta: Meta; + returnHiddenIndices: boolean; + searchQuery?: string; }): { indices: ElasticsearchIndexWithIngestion[]; isInitialRequest: boolean; meta: Meta; + returnHiddenIndices: boolean; + searchQuery?: string; }; + closeDeleteModal(): void; + deleteError: Actions['apiError']; + deleteIndex: Actions['makeRequest']; + deleteSuccess: Actions['apiSuccess']; fetchIndices({ meta, returnHiddenIndices, @@ -43,34 +64,59 @@ export interface IndicesActions { }): { meta: Meta; returnHiddenIndices: boolean; searchQuery?: string }; makeRequest: typeof FetchIndicesAPILogic.actions.makeRequest; onPaginate(newPageIndex: number): { newPageIndex: number }; - setIsFirstRequest(): boolean; + openDeleteModal(indexName: string): { indexName: string }; + setIsFirstRequest(): void; } export interface IndicesValues { data: typeof FetchIndicesAPILogic.values.data; + deleteModalIndexName: string; hasNoIndices: boolean; indices: ElasticsearchViewIndex[]; + isDeleteModalVisible: boolean; isFirstRequest: boolean; isLoading: boolean; meta: Meta; + searchParams: { meta: Meta; returnHiddenIndices: boolean; searchQuery?: string }; status: typeof FetchIndicesAPILogic.values.status; } export const IndicesLogic = kea>({ actions: { + closeDeleteModal: true, fetchIndices: ({ meta, returnHiddenIndices, searchQuery }) => ({ meta, returnHiddenIndices, searchQuery, }), onPaginate: (newPageIndex) => ({ newPageIndex }), - setIsFirstRequest: () => true, + openDeleteModal: (indexName) => ({ indexName }), + setIsFirstRequest: true, }, connect: { - actions: [FetchIndicesAPILogic, ['makeRequest', 'apiSuccess', 'apiError']], + actions: [ + FetchIndicesAPILogic, + ['makeRequest', 'apiSuccess', 'apiError'], + DeleteIndexApiLogic, + ['apiError as deleteError', 'apiSuccess as deleteSuccess', 'makeRequest as deleteIndex'], + ], values: [FetchIndicesAPILogic, ['data', 'status']], }, - listeners: ({ actions }) => ({ + listeners: ({ actions, values }) => ({ apiError: (e) => flashAPIErrors(e), + deleteError: (e) => flashAPIErrors(e), + deleteSuccess: () => { + flashSuccessToast( + i18n.translate('xpack.enterpriseSearch.content.indices.deleteIndex.successToast.title', { + defaultMessage: + 'Your index {indexName} and any associated connectors or crawlers were successfully deleted', + values: { + indexName: values.deleteModalIndexName, + }, + }) + ); + actions.closeDeleteModal(); + actions.fetchIndices(values.searchParams); + }, fetchIndices: async (input, breakpoint) => { await breakpoint(150); actions.makeRequest(input); @@ -79,6 +125,20 @@ export const IndicesLogic = kea>({ }), path: ['enterprise_search', 'content', 'indices_logic'], reducers: () => ({ + deleteModalIndexName: [ + '', + { + closeDeleteModal: () => '', + openDeleteModal: (_, { indexName }) => indexName, + }, + ], + isDeleteModalVisible: [ + false, + { + closeDeleteModal: () => false, + openDeleteModal: () => true, + }, + ], isFirstRequest: [ true, { @@ -87,11 +147,18 @@ export const IndicesLogic = kea>({ setIsFirstRequest: () => true, }, ], - meta: [ - DEFAULT_META, + searchParams: [ + { meta: DEFAULT_META, returnHiddenIndices: false }, { - apiSuccess: (_, { meta }) => meta, - onPaginate: (state, { newPageIndex }) => updateMetaPageIndex(state, newPageIndex), + apiSuccess: (_, { meta, returnHiddenIndices, searchQuery }) => ({ + meta, + returnHiddenIndices, + searchQuery, + }), + onPaginate: (state, { newPageIndex }) => ({ + ...state, + meta: updateMetaPageIndex(state.meta, newPageIndex), + }), }, ], }), @@ -110,5 +177,6 @@ export const IndicesLogic = kea>({ () => [selectors.status, selectors.isFirstRequest], (status, isFirstRequest) => [Status.LOADING, Status.IDLE].includes(status) && isFirstRequest, ], + meta: [() => [selectors.searchParams], (searchParams) => searchParams.meta], }), }); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_table.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_table.tsx index d68ce14b1b183..0462613b247d8 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_table.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_table.tsx @@ -11,6 +11,7 @@ import { CriteriaWithPagination, EuiBasicTable, EuiBasicTableColumn, + EuiButtonIcon, EuiIcon, EuiText, } from '@elastic/eui'; @@ -37,122 +38,12 @@ const healthColorsMap = { yellow: 'warning', }; -const columns: Array> = [ - { - field: 'name', - name: i18n.translate('xpack.enterpriseSearch.content.searchIndices.name.columnTitle', { - defaultMessage: 'Index name', - }), - render: (name: string) => ( - - {name} - - ), - sortable: true, - truncateText: true, - width: '40%', - }, - { - field: 'health', - name: i18n.translate('xpack.enterpriseSearch.content.searchIndices.health.columnTitle', { - defaultMessage: 'Index health', - }), - render: (health: 'red' | 'green' | 'yellow' | 'unavailable') => ( - - -  {health ?? '-'} - - ), - sortable: true, - truncateText: true, - width: '10%', - }, - { - field: 'count', - name: i18n.translate('xpack.enterpriseSearch.content.searchIndices.docsCount.columnTitle', { - defaultMessage: 'Docs count', - }), - sortable: true, - truncateText: true, - width: '10%', - }, - { - field: 'ingestionMethod', - name: i18n.translate( - 'xpack.enterpriseSearch.content.searchIndices.ingestionMethod.columnTitle', - { - defaultMessage: 'Ingestion method', - } - ), - render: (ingestionMethod: IngestionMethod) => ( - {ingestionMethodToText(ingestionMethod)} - ), - truncateText: true, - width: '10%', - }, - { - name: i18n.translate( - 'xpack.enterpriseSearch.content.searchIndices.ingestionStatus.columnTitle', - { - defaultMessage: 'Ingestion status', - } - ), - render: (index: ElasticsearchViewIndex) => { - const overviewPath = generateEncodedPath(SEARCH_INDEX_PATH, { indexName: index.name }); - if (isCrawlerIndex(index)) { - const label = crawlerStatusToText(index.crawler?.most_recent_crawl_request_status); - - return ( - - ); - } else { - const label = ingestionStatusToText(index.ingestionStatus); - return ( - - ); - } - }, - truncateText: true, - width: '10%', - }, - { - actions: [ - { - render: ({ name }) => ( - - ), - }, - ], - name: i18n.translate('xpack.enterpriseSearch.content.searchIndices.actions.columnTitle', { - defaultMessage: 'Actions', - }), - width: '5%', - }, -]; - interface IndicesTableProps { indices: ElasticsearchViewIndex[]; isLoading?: boolean; meta: Meta; onChange: (criteria: CriteriaWithPagination) => void; + onDelete: (indexName: string) => void; } export const IndicesTable: React.FC = ({ @@ -160,13 +51,141 @@ export const IndicesTable: React.FC = ({ isLoading, meta, onChange, -}) => ( - -); + onDelete, +}) => { + const columns: Array> = [ + { + field: 'name', + name: i18n.translate('xpack.enterpriseSearch.content.searchIndices.name.columnTitle', { + defaultMessage: 'Index name', + }), + render: (name: string) => ( + + {name} + + ), + sortable: true, + truncateText: true, + width: '40%', + }, + { + field: 'health', + name: i18n.translate('xpack.enterpriseSearch.content.searchIndices.health.columnTitle', { + defaultMessage: 'Index health', + }), + render: (health: 'red' | 'green' | 'yellow' | 'unavailable') => ( + + +  {health ?? '-'} + + ), + sortable: true, + truncateText: true, + width: '10%', + }, + { + field: 'count', + name: i18n.translate('xpack.enterpriseSearch.content.searchIndices.docsCount.columnTitle', { + defaultMessage: 'Docs count', + }), + sortable: true, + truncateText: true, + width: '10%', + }, + { + field: 'ingestionMethod', + name: i18n.translate( + 'xpack.enterpriseSearch.content.searchIndices.ingestionMethod.columnTitle', + { + defaultMessage: 'Ingestion method', + } + ), + render: (ingestionMethod: IngestionMethod) => ( + {ingestionMethodToText(ingestionMethod)} + ), + truncateText: true, + width: '10%', + }, + { + name: i18n.translate( + 'xpack.enterpriseSearch.content.searchIndices.ingestionStatus.columnTitle', + { + defaultMessage: 'Ingestion status', + } + ), + render: (index: ElasticsearchViewIndex) => { + const overviewPath = generateEncodedPath(SEARCH_INDEX_PATH, { indexName: index.name }); + if (isCrawlerIndex(index)) { + const label = crawlerStatusToText(index.crawler?.most_recent_crawl_request_status); + + return ( + + ); + } else { + const label = ingestionStatusToText(index.ingestionStatus); + return ( + + ); + } + }, + truncateText: true, + width: '10%', + }, + { + actions: [ + { + render: ({ name }) => ( + + ), + }, + { + render: (index) => + // We don't have a way to delete crawlers yet + isCrawlerIndex(index) ? ( + <> + ) : ( + onDelete(index.name)} + /> + ), + }, + ], + name: i18n.translate('xpack.enterpriseSearch.content.searchIndices.actions.columnTitle', { + defaultMessage: 'Actions', + }), + width: '5%', + }, + ]; + return ( + + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/search_indices.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/search_indices.tsx index 96019c8139c97..bc9aa175e1c71 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/search_indices.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/search_indices.tsx @@ -34,6 +34,7 @@ import { useLocalStorage } from '../../../shared/use_local_storage'; import { NEW_INDEX_PATH } from '../../routes'; import { EnterpriseSearchContentPageTemplate } from '../layout/page_template'; +import { DeleteIndexModal } from './delete_index_modal'; import { IndicesLogic } from './indices_logic'; import { IndicesTable } from './indices_table'; @@ -49,7 +50,7 @@ export const baseBreadcrumbs = [ ]; export const SearchIndices: React.FC = () => { - const { fetchIndices, onPaginate, setIsFirstRequest } = useActions(IndicesLogic); + const { fetchIndices, onPaginate, openDeleteModal, setIsFirstRequest } = useActions(IndicesLogic); const { meta, indices, hasNoIndices, isLoading } = useValues(IndicesLogic); const [showHiddenIndices, setShowHiddenIndices] = useState(false); const [searchQuery, setSearchValue] = useState(''); @@ -85,6 +86,7 @@ export const SearchIndices: React.FC = () => { return ( <> + { - + ) : ( diff --git a/x-pack/plugins/enterprise_search/server/lib/analytics/fetch_analytics_collection.test.ts b/x-pack/plugins/enterprise_search/server/lib/analytics/fetch_analytics_collection.test.ts index e157df1df16f6..6fb4e55dd6361 100644 --- a/x-pack/plugins/enterprise_search/server/lib/analytics/fetch_analytics_collection.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/analytics/fetch_analytics_collection.test.ts @@ -9,7 +9,10 @@ import { IScopedClusterClient } from '@kbn/core-elasticsearch-server'; import { ANALYTICS_COLLECTIONS_INDEX } from '../..'; -import { fetchAnalyticsCollectionByName } from './fetch_analytics_collection'; +import { + fetchAnalyticsCollectionByName, + fetchAnalyticsCollections, +} from './fetch_analytics_collection'; import { setupAnalyticsCollectionIndex } from './setup_indices'; jest.mock('./setup_indices', () => ({ @@ -28,6 +31,75 @@ describe('fetch analytics collection lib function', () => { jest.clearAllMocks(); }); + describe('fetch collections', () => { + it('should return a list of analytics collections', async () => { + mockClient.asCurrentUser.search.mockImplementationOnce(() => + Promise.resolve({ + hits: { + hits: [ + { _id: '2', _source: { name: 'example' } }, + { _id: '1', _source: { name: 'example2' } }, + ], + }, + }) + ); + await expect( + fetchAnalyticsCollections(mockClient as unknown as IScopedClusterClient) + ).resolves.toEqual([ + { id: '2', name: 'example' }, + { id: '1', name: 'example2' }, + ]); + }); + + it('should setup the indexes if none exist and return an empty array', async () => { + mockClient.asCurrentUser.search.mockImplementationOnce(() => + Promise.reject({ + meta: { + body: { + error: { + type: 'index_not_found_exception', + }, + }, + }, + }) + ); + + await expect( + fetchAnalyticsCollections(mockClient as unknown as IScopedClusterClient) + ).resolves.toEqual([]); + + expect(setupAnalyticsCollectionIndex as jest.Mock).toHaveBeenCalledWith( + mockClient.asCurrentUser + ); + }); + + it('should not call setup analytics index on other errors and return error', async () => { + const error = { + meta: { + body: { + error: { + type: 'other error', + }, + }, + }, + }; + mockClient.asCurrentUser.search.mockImplementationOnce(() => Promise.reject(error)); + await expect( + fetchAnalyticsCollections(mockClient as unknown as IScopedClusterClient) + ).rejects.toMatchObject(error); + + expect(mockClient.asCurrentUser.search).toHaveBeenCalledWith({ + from: 0, + index: ANALYTICS_COLLECTIONS_INDEX, + query: { + match_all: {}, + }, + size: 1000, + }); + expect(setupAnalyticsCollectionIndex as jest.Mock).not.toHaveBeenCalled(); + }); + }); + describe('fetch collection by name', () => { it('should fetch analytics collection by name', async () => { mockClient.asCurrentUser.search.mockImplementationOnce(() => diff --git a/x-pack/plugins/enterprise_search/server/lib/analytics/fetch_analytics_collection.ts b/x-pack/plugins/enterprise_search/server/lib/analytics/fetch_analytics_collection.ts index 46f718d23976d..ef356ae2bca2c 100644 --- a/x-pack/plugins/enterprise_search/server/lib/analytics/fetch_analytics_collection.ts +++ b/x-pack/plugins/enterprise_search/server/lib/analytics/fetch_analytics_collection.ts @@ -5,12 +5,14 @@ * 2.0. */ +import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { IScopedClusterClient } from '@kbn/core-elasticsearch-server'; import { ANALYTICS_COLLECTIONS_INDEX } from '../..'; import { AnalyticsCollection } from '../../../common/types/analytics'; import { isIndexNotFoundException } from '../../utils/identify_exceptions'; +import { fetchAll } from '../fetch_all'; import { setupAnalyticsCollectionIndex } from './setup_indices'; @@ -36,3 +38,19 @@ export const fetchAnalyticsCollectionByName = async ( return undefined; } }; + +export const fetchAnalyticsCollections = async ( + client: IScopedClusterClient +): Promise => { + const query: QueryDslQueryContainer = { match_all: {} }; + + try { + return await fetchAll(client, ANALYTICS_COLLECTIONS_INDEX, query); + } catch (error) { + if (isIndexNotFoundException(error)) { + await setupAnalyticsCollectionIndex(client.asCurrentUser); + return []; + } + throw error; + } +}; diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/analytics.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/analytics.ts index be53b797239a1..7035329e4d314 100644 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/analytics.ts +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/analytics.ts @@ -11,11 +11,24 @@ import { i18n } from '@kbn/i18n'; import { ErrorCode } from '../../../common/types/error_codes'; import { addAnalyticsCollection } from '../../lib/analytics/add_analytics_collection'; +import { fetchAnalyticsCollections } from '../../lib/analytics/fetch_analytics_collection'; import { RouteDependencies } from '../../plugin'; import { createError } from '../../utils/create_error'; import { elasticsearchErrorHandler } from '../../utils/elasticsearch_error_handler'; export function registerAnalyticsRoutes({ router, log }: RouteDependencies) { + router.get( + { + path: '/internal/enterprise_search/analytics/collections', + validate: {}, + }, + elasticsearchErrorHandler(log, async (context, request, response) => { + const { client } = (await context.core).elasticsearch; + const collections = await fetchAnalyticsCollections(client); + return response.ok({ body: collections }); + }) + ); + router.post( { path: '/internal/enterprise_search/analytics/collections', diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts index 5d5f72c297727..6741721053b86 100644 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts @@ -9,6 +9,7 @@ import { schema } from '@kbn/config-schema'; import { i18n } from '@kbn/i18n'; import { ErrorCode } from '../../../common/types/error_codes'; +import { deleteConnectorById } from '../../lib/connectors/delete_connector'; import { fetchConnectorByIndexName, fetchConnectors } from '../../lib/connectors/fetch_connectors'; import { fetchCrawlerByIndexName, fetchCrawlers } from '../../lib/crawler/fetch_crawlers'; @@ -124,6 +125,52 @@ export function registerIndexRoutes({ router, log }: RouteDependencies) { }) ); + router.delete( + { + path: '/internal/enterprise_search/indices/{indexName}', + validate: { + params: schema.object({ + indexName: schema.string(), + }), + }, + }, + elasticsearchErrorHandler(log, async (context, request, response) => { + const indexName = decodeURIComponent(request.params.indexName); + const { client } = (await context.core).elasticsearch; + + try { + const connector = await fetchConnectorByIndexName(client, indexName); + const crawler = await fetchCrawlerByIndexName(client, indexName); + + if (connector) { + await deleteConnectorById(client, connector.id); + } + + if (crawler) { + // do nothing for now because we don't have a way to delete a crawler yet + } + + await client.asCurrentUser.indices.delete({ index: indexName }); + + return response.ok({ + body: {}, + headers: { 'content-type': 'application/json' }, + }); + } catch (error) { + if (isIndexNotFoundException(error)) { + return createError({ + errorCode: ErrorCode.INDEX_NOT_FOUND, + message: 'Could not find index', + response, + statusCode: 404, + }); + } + + throw error; + } + }) + ); + router.get( { path: '/internal/enterprise_search/indices/{indexName}/exists', diff --git a/x-pack/plugins/lens/public/app_plugin/app.test.tsx b/x-pack/plugins/lens/public/app_plugin/app.test.tsx index 03cf38f141f0d..7f166cb54e299 100644 --- a/x-pack/plugins/lens/public/app_plugin/app.test.tsx +++ b/x-pack/plugins/lens/public/app_plugin/app.test.tsx @@ -1415,7 +1415,8 @@ describe('Lens App', () => { layers: [ { indexPatternId: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - timeFieldName: 'order_date', + xFieldName: 'order_date', + xMode: 'date_histogram', chartType: 'area', axisPosition: 'left', palette: { diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.test.ts b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.test.ts index 5cc62012a5094..e566443640d85 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.test.ts +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.test.ts @@ -288,7 +288,8 @@ describe('suggestion helpers', () => { layers: [ { indexPatternId: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - timeFieldName: 'order_date', + xFieldName: 'order_date', + xMode: 'date_histogram', chartType: 'area', axisPosition: 'left', palette: { @@ -369,7 +370,8 @@ describe('suggestion helpers', () => { layers: [ { indexPatternId: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - timeFieldName: 'order_date', + xFieldName: 'order_date', + xMode: 'date_histogram', chartType: 'area', axisPosition: 'left', palette: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx index 90f59f5470e37..e90ed2c781d5a 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx @@ -1504,7 +1504,8 @@ describe('IndexPattern Data Source suggestions', () => { const context = [ { indexPatternId: '1', - timeFieldName: 'timestamp', + xFieldName: 'timestamp', + xMode: 'date_histogram', chartType: 'area', axisPosition: 'left', palette: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts index 319c309cac036..382df0c9b53dd 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts @@ -178,10 +178,8 @@ function getEmptyLayersSuggestionsForVisualizeCharts( if (!indexPattern) return []; const newId = generateId(); - let newLayer: IndexPatternLayer | undefined; - if (indexPattern.timeFieldName) { - newLayer = createNewTimeseriesLayerWithMetricAggregationFromVizEditor(indexPattern, layer); - } + const newLayer: IndexPatternLayer | undefined = + createNewLayerWithMetricAggregationFromVizEditor(indexPattern, layer); if (newLayer) { const suggestion = buildSuggestion({ state, @@ -197,13 +195,13 @@ function getEmptyLayersSuggestionsForVisualizeCharts( return suggestions; } -function createNewTimeseriesLayerWithMetricAggregationFromVizEditor( +function createNewLayerWithMetricAggregationFromVizEditor( indexPattern: IndexPattern, layer: VisualizeEditorLayersContext ): IndexPatternLayer | undefined { - const { timeFieldName, splitMode, splitFilters, metrics, timeInterval, dropPartialBuckets } = + const { splitMode, splitFilters, metrics, timeInterval, dropPartialBuckets, xMode, xFieldName } = layer; - const dateField = indexPattern.getFieldByName(timeFieldName!); + const xField = xFieldName ? indexPattern.getFieldByName(xFieldName) : undefined; const splitFields = layer.splitFields ? (layer.splitFields @@ -213,10 +211,10 @@ function createNewTimeseriesLayerWithMetricAggregationFromVizEditor( // generate the layer for split by terms if (splitMode === 'terms' && splitFields?.length) { - return getSplitByTermsLayer(indexPattern, splitFields, dateField, layer); + return getSplitByTermsLayer(indexPattern, splitFields, xField, xMode, layer); // generate the layer for split by filters } else if (splitMode?.includes('filter') && splitFilters && splitFilters.length) { - return getSplitByFiltersLayer(indexPattern, dateField, layer); + return getSplitByFiltersLayer(indexPattern, xField, xMode, layer); } else { const copyMetricsArray = [...metrics]; const computedLayer = computeLayerFromContext( @@ -231,11 +229,15 @@ function createNewTimeseriesLayerWithMetricAggregationFromVizEditor( return computedLayer; } + if (!xField || !xMode) { + return computedLayer; + } + return insertNewColumn({ - op: 'date_histogram', + op: xMode, layer: computedLayer, columnId: generateId(), - field: dateField, + field: xField, indexPattern, visualizationGroups: [], columnParams: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts index 3a85a317eec0f..80f6eaecd3a8a 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts @@ -148,7 +148,8 @@ describe('loader', () => { layers: [ { indexPatternId: '1', - timeFieldName: 'timestamp', + xFieldName: 'timestamp', + xMode: 'date_histogram', chartType: 'area', axisPosition: 'left', metrics: [], diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts index 3d079584e32f9..634ed490e11cc 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts @@ -1651,7 +1651,9 @@ export function computeLayerFromContext( FormulaIndexPatternColumn, 'managedReference' >; - const tempLayer = { indexPatternId: indexPattern.id, columns: {}, columnOrder: [] }; + const tempLayer = isLast + ? { indexPatternId: indexPattern.id, columns: {}, columnOrder: [] } + : computeLayerFromContext(metricsArray.length === 1, metricsArray, indexPattern); let newColumn = operationDefinition.buildColumn({ indexPattern, layer: tempLayer, @@ -1740,7 +1742,8 @@ export function computeLayerFromContext( export function getSplitByTermsLayer( indexPattern: IndexPattern, splitFields: IndexPatternField[], - dateField: IndexPatternField | undefined, + xField: IndexPatternField | undefined, + xMode: string | undefined, layer: VisualizeEditorLayersContext ): IndexPatternLayer { const { termsParams, metrics, timeInterval, splitWithDateHistogram, dropPartialBuckets } = layer; @@ -1759,18 +1762,21 @@ export function getSplitByTermsLayer( let termsLayer = insertNewColumn({ op: splitWithDateHistogram ? 'date_histogram' : 'terms', - layer: insertNewColumn({ - op: 'date_histogram', - layer: computedLayer, - columnId: generateId(), - field: dateField, - indexPattern, - visualizationGroups: [], - columnParams: { - interval: timeInterval, - dropPartials: dropPartialBuckets, - }, - }), + layer: + xField && xMode + ? insertNewColumn({ + op: xMode, + layer: computedLayer, + columnId: generateId(), + field: xField, + indexPattern, + visualizationGroups: [], + columnParams: { + interval: timeInterval, + dropPartials: dropPartialBuckets, + }, + }) + : computedLayer, columnId, field: baseField, indexPattern, @@ -1821,7 +1827,8 @@ export function getSplitByTermsLayer( export function getSplitByFiltersLayer( indexPattern: IndexPattern, - dateField: IndexPatternField | undefined, + xField: IndexPatternField | undefined, + xMode: string | undefined, layer: VisualizeEditorLayersContext ): IndexPatternLayer { const { splitFilters, metrics, timeInterval, dropPartialBuckets } = layer; @@ -1847,18 +1854,21 @@ export function getSplitByFiltersLayer( const columnId = generateId(); let filtersLayer = insertNewColumn({ op: 'filters', - layer: insertNewColumn({ - op: 'date_histogram', - layer: computedLayer, - columnId: generateId(), - field: dateField, - indexPattern, - visualizationGroups: [], - columnParams: { - interval: timeInterval, - dropPartials: dropPartialBuckets, - }, - }), + layer: + xField && xMode + ? insertNewColumn({ + op: xMode, + layer: computedLayer, + columnId: generateId(), + field: xField, + indexPattern, + visualizationGroups: [], + columnParams: { + interval: timeInterval, + dropPartials: dropPartialBuckets, + }, + }) + : computedLayer, columnId, field: undefined, indexPattern, diff --git a/x-pack/plugins/lens/public/types.ts b/x-pack/plugins/lens/public/types.ts index d79a9b7579536..97df24648f4d4 100644 --- a/x-pack/plugins/lens/public/types.ts +++ b/x-pack/plugins/lens/public/types.ts @@ -229,6 +229,9 @@ interface ChartSettings { fill?: string; legend?: Record; gridLinesVisibility?: Record; + tickLabelsVisibility?: Record; + axisTitlesVisibility?: Record; + valueLabels?: boolean; extents?: { yLeftExtent: AxisExtents; yRightExtent: AxisExtents; diff --git a/x-pack/plugins/lens/public/visualizations/xy/visualization.test.ts b/x-pack/plugins/lens/public/visualizations/xy/visualization.test.ts index 6817046864783..ad26ea92762bf 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/visualization.test.ts +++ b/x-pack/plugins/lens/public/visualizations/xy/visualization.test.ts @@ -971,7 +971,8 @@ describe('xy_visualization', () => { layers: [ { indexPatternId: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - timeFieldName: 'order_date', + xFieldName: 'order_date', + xMode: 'date_histogram', chartType: 'area', axisPosition: 'left', palette: { diff --git a/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx b/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx index e0d0a19cebec8..24710c3261cdb 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx @@ -452,7 +452,10 @@ export const getXyVisualization = ({ yLeftExtent: context.configuration.extents?.yLeftExtent, legend: context.configuration.legend, gridlinesVisibilitySettings: context.configuration.gridLinesVisibility, + tickLabelsVisibilitySettings: context.configuration.tickLabelsVisibility, + axisTitlesVisibilitySettings: context.configuration.axisTitlesVisibility, valuesInLegend: true, + valueLabels: context.configuration.valueLabels ? 'show' : 'hide', layers: visualizationStateLayers, }, }; diff --git a/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.test.ts b/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.test.ts index 96505d2b5f963..52702c014f0cb 100644 --- a/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.test.ts +++ b/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.test.ts @@ -23,11 +23,12 @@ import { Actions } from '../authorization'; import type { SavedObjectActions } from '../authorization/actions/saved_object'; import { SecureSavedObjectsClientWrapper } from './secure_saved_objects_client_wrapper'; -jest.mock('@kbn/core/server/saved_objects/service/lib/utils', () => { - const { SavedObjectsUtils } = jest.requireActual( - '@kbn/core/server/saved_objects/service/lib/utils' +jest.mock('@kbn/core-saved-objects-utils-server', () => { + const { SavedObjectsUtils, ...actual } = jest.requireActual( + '@kbn/core-saved-objects-utils-server' ); return { + ...actual, SavedObjectsUtils: { ...SavedObjectsUtils, createEmptyFindResponse: SavedObjectsUtils.createEmptyFindResponse, diff --git a/x-pack/plugins/security_solution/server/__mocks__/core.mock.ts b/x-pack/plugins/security_solution/server/__mocks__/core.mock.ts index 57feaedbc9487..1ae9b046dc636 100644 --- a/x-pack/plugins/security_solution/server/__mocks__/core.mock.ts +++ b/x-pack/plugins/security_solution/server/__mocks__/core.mock.ts @@ -8,8 +8,8 @@ // See: https://github.com/elastic/kibana/issues/117255, this creates mocks to avoid memory leaks from kibana core. // We _must_ import from the restricted path or we pull in _everything_ including memory leaks from Kibana core -import { SavedObjectsUtils } from '@kbn/core/server/saved_objects/service/lib/utils'; -import { SavedObjectsErrorHelpers } from '@kbn/core/server/saved_objects/service/lib/errors'; +import { SavedObjectsUtils, SavedObjectsErrorHelpers } from '@kbn/core-saved-objects-utils-server'; + module.exports = { SavedObjectsUtils, SavedObjectsErrorHelpers, diff --git a/x-pack/plugins/task_manager/server/task_store.test.ts b/x-pack/plugins/task_manager/server/task_store.test.ts index e7696102db8ca..561d4ac6a0989 100644 --- a/x-pack/plugins/task_manager/server/task_store.test.ts +++ b/x-pack/plugins/task_manager/server/task_store.test.ts @@ -15,20 +15,15 @@ import { TaskLifecycleResult, SerializedConcreteTaskInstance, } from './task'; -import { elasticsearchServiceMock } from '@kbn/core/server/mocks'; +import { elasticsearchServiceMock, savedObjectsServiceMock } from '@kbn/core/server/mocks'; import { TaskStore, SearchOpts, AggregationOpts } from './task_store'; import { savedObjectsRepositoryMock } from '@kbn/core/server/mocks'; -import { - SavedObjectsSerializer, - SavedObjectTypeRegistry, - SavedObjectAttributes, - SavedObjectsErrorHelpers, -} from '@kbn/core/server'; +import { SavedObjectAttributes, SavedObjectsErrorHelpers } from '@kbn/core/server'; import { TaskTypeDictionary } from './task_type_dictionary'; import { mockLogger } from './test_utils'; const savedObjectsClient = savedObjectsRepositoryMock.create(); -const serializer = new SavedObjectsSerializer(new SavedObjectTypeRegistry()); +const serializer = savedObjectsServiceMock.createSerializer(); beforeEach(() => jest.resetAllMocks()); diff --git a/x-pack/plugins/threat_intelligence/public/common/mocks/mock_security_context.tsx b/x-pack/plugins/threat_intelligence/public/common/mocks/mock_security_context.tsx new file mode 100644 index 0000000000000..666fc6318c577 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/common/mocks/mock_security_context.tsx @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { SecuritySolutionPluginContext } from '../..'; + +export const getSecuritySolutionContextMock = (): SecuritySolutionPluginContext => ({ + getFiltersGlobalComponent: + () => + ({ children }) => +
{children}
, + licenseService: { + isEnterprise() { + return true; + }, + }, + sourcererDataView: { + browserFields: {}, + selectedPatterns: [], + indexPattern: { fields: [], title: '' }, + }, +}); diff --git a/x-pack/plugins/threat_intelligence/public/common/mocks/story_providers.tsx b/x-pack/plugins/threat_intelligence/public/common/mocks/story_providers.tsx new file mode 100644 index 0000000000000..752e93b756ddb --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/common/mocks/story_providers.tsx @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { ReactNode, VFC } from 'react'; +import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public'; +import { DataPublicPluginStart } from '@kbn/data-plugin/public'; +import { CoreStart, IUiSettingsClient } from '@kbn/core/public'; +import { SecuritySolutionContext } from '../../containers/security_solution_context'; +import { getSecuritySolutionContextMock } from './mock_security_context'; + +export interface KibanaContextMock { + /** + * For the data plugin (see {@link DataPublicPluginStart}) + */ + data?: DataPublicPluginStart; + /** + * For the core ui-settings package (see {@link IUiSettingsClient}) + */ + uiSettings?: IUiSettingsClient; +} + +export interface StoryProvidersComponentProps { + /** + * Used to generate a new KibanaReactContext (using {@link createKibanaReactContext}) + */ + kibana: KibanaContextMock; + /** + * Component(s) to be displayed inside + */ + children: ReactNode; +} + +/** + * Helper functional component used in Storybook stories. + * Wraps the story with our {@link SecuritySolutionContext} and KibanaReactContext. + */ +export const StoryProvidersComponent: VFC = ({ + children, + kibana, +}) => { + const KibanaReactContext = createKibanaReactContext(kibana as CoreStart); + const securitySolutionContextMock = getSecuritySolutionContextMock(); + + return ( + + {children} + + ); +}; diff --git a/x-pack/plugins/threat_intelligence/public/common/mocks/test_providers.tsx b/x-pack/plugins/threat_intelligence/public/common/mocks/test_providers.tsx index afd526342689b..a2c0318c482aa 100644 --- a/x-pack/plugins/threat_intelligence/public/common/mocks/test_providers.tsx +++ b/x-pack/plugins/threat_intelligence/public/common/mocks/test_providers.tsx @@ -14,6 +14,7 @@ import type { IStorage } from '@kbn/kibana-utils-plugin/public'; import { Storage } from '@kbn/kibana-utils-plugin/public'; import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; import { BehaviorSubject } from 'rxjs'; +import { getSecuritySolutionContextMock } from './mock_security_context'; import { mockUiSetting } from './mock_kibana_ui_setting'; import { KibanaContext } from '../../hooks/use_kibana'; import { SecuritySolutionPluginContext } from '../../types'; @@ -95,22 +96,7 @@ const coreServiceMock = { uiSettings: { get: jest.fn().mockImplementation(mockUiSetting) }, }; -const mockSecurityContext: SecuritySolutionPluginContext = { - getFiltersGlobalComponent: - () => - ({ children }) => -
{children}
, - licenseService: { - isEnterprise() { - return true; - }, - }, - sourcererDataView: { - browserFields: {}, - selectedPatterns: [], - indexPattern: { fields: [], title: '' }, - }, -}; +const mockSecurityContext: SecuritySolutionPluginContext = getSecuritySolutionContextMock(); export const mockedServices = { ...coreServiceMock, diff --git a/x-pack/plugins/threat_intelligence/public/components/paywall/index.tsx b/x-pack/plugins/threat_intelligence/public/components/paywall/index.tsx new file mode 100644 index 0000000000000..46d2df81a1c8c --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/components/paywall/index.tsx @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './paywall'; diff --git a/x-pack/plugins/threat_intelligence/public/components/paywall/paywall.stories.tsx b/x-pack/plugins/threat_intelligence/public/components/paywall/paywall.stories.tsx new file mode 100644 index 0000000000000..14de7d5b907fb --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/components/paywall/paywall.stories.tsx @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { Paywall } from './paywall'; + +export default { + component: BasicPaywall, + title: 'Paywall', +}; + +export function BasicPaywall() { + return ; +} diff --git a/x-pack/plugins/threat_intelligence/public/components/paywall/paywall.tsx b/x-pack/plugins/threat_intelligence/public/components/paywall/paywall.tsx new file mode 100644 index 0000000000000..8f095a2fd9baa --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/components/paywall/paywall.tsx @@ -0,0 +1,74 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { VFC } from 'react'; +import { + EuiButton, + EuiButtonEmpty, + EuiEmptyPrompt, + EuiFlexGroup, + EuiFlexItem, + EuiIcon, +} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; + +interface PaywallProps { + /** + * Can be obtained using `http.basePath.prepend('/app/management/stack/license_management')` + */ + licenseManagementHref: string; +} + +export const Paywall: VFC = ({ licenseManagementHref }) => { + return ( + } + color="subdued" + data-test-subj="tiPaywall" + title={ +

+ +

+ } + body={ +

+ +

+ } + actions={ + + +
+ + + +
+
+ +
+ + + +
+
+
+ } + /> + ); +}; diff --git a/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.test.tsx b/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.test.tsx index 4c0abd97f154d..a01c3b94e1cd4 100644 --- a/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.test.tsx +++ b/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.test.tsx @@ -7,6 +7,7 @@ import { render, screen } from '@testing-library/react'; import React from 'react'; +import { TestProvidersComponent } from '../../common/mocks/test_providers'; import { SecuritySolutionPluginContext } from '../../types'; import { SecuritySolutionContext } from '../security_solution_context'; import { EnterpriseGuard } from './enterprise_guard'; @@ -15,17 +16,19 @@ describe('', () => { describe('when on enterprise plan', () => { it('should render specified children', () => { render( - - -
enterprise only content
-
-
+ + + +
enterprise only content
+
+
+
); expect(screen.queryByText('enterprise only content')).toBeInTheDocument(); @@ -35,21 +38,23 @@ describe('', () => { describe('when not on enterprise plan', () => { it('should render specified children', () => { render( - - fallback for non enterprise}> -
enterprise only content
-
-
+ + + +
enterprise only content
+
+
+
); expect(screen.queryByText('enterprise only content')).not.toBeInTheDocument(); - expect(screen.queryByText('fallback for non enterprise')).toBeInTheDocument(); + expect(screen.queryByTestId('tiPaywall')).toBeInTheDocument(); }); }); }); diff --git a/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.tsx b/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.tsx index 67351c1e3d149..06ca98973af09 100644 --- a/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.tsx +++ b/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.tsx @@ -5,20 +5,25 @@ * 2.0. */ -import React, { ReactElement } from 'react'; +import React from 'react'; import { FC } from 'react'; +import { Paywall } from '../../components/paywall'; +import { useKibana } from '../../hooks/use_kibana'; import { useSecurityContext } from '../../hooks/use_security_context'; -interface EnterpriseGuardProps { - fallback?: ReactElement; -} - -export const EnterpriseGuard: FC = ({ children, fallback = null }) => { +export const EnterpriseGuard: FC = ({ children }) => { const { licenseService } = useSecurityContext(); + const { + services: { http }, + } = useKibana(); if (licenseService.isEnterprise()) { return <>{children}; } - return fallback; + return ( + + ); }; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_barchart_wrapper/indicators_barchart_wrapper.stories.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_barchart_wrapper/indicators_barchart_wrapper.stories.tsx index 1f4cbce1c76a2..478b2ec398b97 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_barchart_wrapper/indicators_barchart_wrapper.stories.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_barchart_wrapper/indicators_barchart_wrapper.stories.tsx @@ -7,12 +7,14 @@ import moment from 'moment'; import React from 'react'; +import { MemoryRouter } from 'react-router-dom'; import { of } from 'rxjs'; import { Story } from '@storybook/react'; import { DataView, DataViewField } from '@kbn/data-views-plugin/common'; -import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public'; -import { CoreStart } from '@kbn/core/public'; import { TimeRange } from '@kbn/es-query'; +import { DataPublicPluginStart } from '@kbn/data-plugin/public'; +import { IUiSettingsClient } from '@kbn/core/public'; +import { StoryProvidersComponent } from '../../../../common/mocks/story_providers'; import { Aggregation, AGGREGATION_NAME } from '../../hooks/use_aggregated_indicators'; import { DEFAULT_TIME_RANGE } from '../../hooks/use_filters/utils'; import { IndicatorsBarChartWrapper } from './indicators_barchart_wrapper'; @@ -74,38 +76,43 @@ const aggregation2: Aggregation = { doc_count: 0, key: '[Filebeat] AbuseCH MalwareBazaar', }; -const KibanaReactContext = createKibanaReactContext({ - data: { - search: { - search: () => - of({ - rawResponse: { - aggregations: { - [AGGREGATION_NAME]: { - buckets: [aggregation1, aggregation2], - }, +const mockData = { + search: { + search: () => + of({ + rawResponse: { + aggregations: { + [AGGREGATION_NAME]: { + buckets: [aggregation1, aggregation2], }, }, - }), - }, - query: { - timefilter: { - timefilter: { - calculateBounds: () => ({ - min: moment(validDate), - max: moment(validDate).add(numberOfDays, 'days'), - }), }, + }), + }, + query: { + timefilter: { + timefilter: { + calculateBounds: () => ({ + min: moment(validDate), + max: moment(validDate).add(numberOfDays, 'days'), + }), }, }, + filterManager: { + getFilters: () => {}, + setFilters: () => {}, + getUpdates$: () => of(), + }, }, - uiSettings: { get: () => {} }, -} as unknown as Partial); +} as unknown as DataPublicPluginStart; + +const mockUiSettings = { get: () => {} } as unknown as IUiSettingsClient; export const Default: Story = () => { return ( - + - + ); }; +Default.decorators = [(story) => {story()}]; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_barchart_wrapper/indicators_barchart_wrapper.test.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_barchart_wrapper/indicators_barchart_wrapper.test.tsx index b8f06c06aa6f5..9deeb4e5bcb8a 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_barchart_wrapper/indicators_barchart_wrapper.test.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_barchart_wrapper/indicators_barchart_wrapper.test.tsx @@ -12,8 +12,11 @@ import { DataView, DataViewField } from '@kbn/data-views-plugin/common'; import { TestProvidersComponent } from '../../../../common/mocks/test_providers'; import { IndicatorsBarChartWrapper } from './indicators_barchart_wrapper'; import { DEFAULT_TIME_RANGE } from '../../hooks/use_filters/utils'; +import { useFilters } from '../../hooks/use_filters'; -const mockIndexPatterns: DataView = { +jest.mock('../../hooks/use_filters'); + +const mockIndexPattern: DataView = { fields: [ { name: '@timestamp', @@ -25,13 +28,26 @@ const mockIndexPatterns: DataView = { } as DataViewField, ], } as DataView; + const mockTimeRange: TimeRange = DEFAULT_TIME_RANGE; +const stub = () => {}; + describe('', () => { + beforeEach(() => { + (useFilters as jest.MockedFunction).mockReturnValue({ + filters: [], + filterQuery: { language: 'kuery', query: '' }, + filterManager: {} as any, + handleSavedQuery: stub, + handleSubmitQuery: stub, + handleSubmitTimeRange: stub, + }); + }); it('should render barchart and field selector dropdown', () => { const component = render( - + ); diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/indicators_table.stories.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/indicators_table.stories.tsx index b8bc912e6208e..0e94e87372820 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/indicators_table.stories.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/indicators_table.stories.tsx @@ -20,7 +20,7 @@ export default { }; const indicatorsFixture: Indicator[] = Array(10).fill(generateMockIndicator()); -const mockIndexPattern: DataView = {} as DataView; +const mockIndexPattern: DataView = undefined as unknown as DataView; const stub = () => void 0; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_aggregated_indicators.test.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_aggregated_indicators.test.tsx index 90bffdb646484..7a671f923f796 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_aggregated_indicators.test.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_aggregated_indicators.test.tsx @@ -21,6 +21,9 @@ import { mockedSearchService, mockedTimefilterService, } from '../../../common/mocks/test_providers'; +import { useFilters } from './use_filters'; + +jest.mock('./use_filters/use_filters'); const aggregationResponse = { rawResponse: { aggregations: { [AGGREGATION_NAME]: { buckets: [] } } }, @@ -35,6 +38,8 @@ const useAggregatedIndicatorsParams: UseAggregatedIndicatorsParam = { timeRange: DEFAULT_TIME_RANGE, }; +const stub = () => {}; + describe('useAggregatedIndicators()', () => { beforeEach(jest.clearAllMocks); @@ -45,6 +50,15 @@ describe('useAggregatedIndicators()', () => { describe('when mounted', () => { beforeEach(() => { + (useFilters as jest.MockedFunction).mockReturnValue({ + filters: [], + filterQuery: { language: 'kuery', query: '' }, + filterManager: {} as any, + handleSavedQuery: stub, + handleSubmitQuery: stub, + handleSubmitTimeRange: stub, + }); + renderHook(() => useAggregatedIndicators(useAggregatedIndicatorsParams), { wrapper: TestProvidersComponent, }); diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_aggregated_indicators.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_aggregated_indicators.ts index 0520991e6593d..9322e84d78c4f 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_aggregated_indicators.ts +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_aggregated_indicators.ts @@ -15,6 +15,7 @@ import { isErrorResponse, TimeRangeBounds, } from '@kbn/data-plugin/common'; +import { useFilters } from './use_filters'; import { convertAggregationToChartSeries } from '../../../common/utils/barchart'; import { RawIndicatorFieldId } from '../../../../common/types/indicator'; import { THREAT_QUERY_BASE } from '../../../../common/constants'; @@ -87,6 +88,8 @@ export const useAggregatedIndicators = ({ [queryService, timeRange] ); + const { filters, filterQuery } = useFilters(); + const loadData = useCallback(async () => { const dateFrom: number = (dateRange.min as moment.Moment).toDate().getTime(); const dateTo: number = (dateRange.max as moment.Moment).toDate().getTime(); @@ -101,8 +104,13 @@ export const useAggregatedIndicators = ({ query: THREAT_QUERY_BASE, language: 'kuery', }, + { + query: filterQuery.query as string, + language: 'kuery', + }, ], [ + ...filters, { query: { range: { @@ -175,6 +183,8 @@ export const useAggregatedIndicators = ({ dateRange.max, dateRange.min, field, + filterQuery, + filters, searchService, selectedPatterns, timeRange.from, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/rbac_legacy.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/rbac_legacy.ts index 4f0f53383e206..7528c6e77acd3 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/rbac_legacy.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/rbac_legacy.ts @@ -6,7 +6,7 @@ */ import expect from '@kbn/expect'; -import { SavedObjectsUtils } from '@kbn/core/server/saved_objects'; +import { SavedObjectsUtils } from '@kbn/core/server'; import { UserAtSpaceScenarios, Superuser } from '../../../scenarios'; import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { ESTestIndexTool, getUrlPrefix, ObjectRemover, AlertUtils } from '../../../../common/lib'; diff --git a/x-pack/test/plugin_api_integration/test_suites/task_manager/migrations.ts b/x-pack/test/plugin_api_integration/test_suites/task_manager/migrations.ts index 644ed91410299..04f34ab50a133 100644 --- a/x-pack/test/plugin_api_integration/test_suites/task_manager/migrations.ts +++ b/x-pack/test/plugin_api_integration/test_suites/task_manager/migrations.ts @@ -13,7 +13,7 @@ import { TaskInstanceWithDeprecatedFields, TaskStatus, } from '@kbn/task-manager-plugin/server/task'; -import { SavedObjectsUtils } from '@kbn/core/server/saved_objects'; +import { SavedObjectsUtils } from '@kbn/core/server'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; export default function createGetTests({ getService }: FtrProviderContext) { diff --git a/x-pack/test/spaces_api_integration/common/suites/disable_legacy_url_aliases.ts b/x-pack/test/spaces_api_integration/common/suites/disable_legacy_url_aliases.ts index f9d1fe6b97236..f95267a02ab3f 100644 --- a/x-pack/test/spaces_api_integration/common/suites/disable_legacy_url_aliases.ts +++ b/x-pack/test/spaces_api_integration/common/suites/disable_legacy_url_aliases.ts @@ -8,7 +8,7 @@ import expect from '@kbn/expect'; import { SuperTest } from 'supertest'; import type { Client } from '@elastic/elasticsearch'; -import { LegacyUrlAlias } from '@kbn/core/server/saved_objects/object_types'; +import type { LegacyUrlAlias } from '@kbn/core-saved-objects-base-server-internal'; import { SPACES } from '../lib/spaces'; import { getUrlPrefix } from '../../../saved_object_api_integration/common/lib/saved_object_test_utils'; import { diff --git a/yarn.lock b/yarn.lock index 83f67be271aa2..d390141ba0e8b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3377,6 +3377,14 @@ version "0.0.0" uid "" +"@kbn/core-saved-objects-base-server-internal@link:bazel-bin/packages/core/saved-objects/core-saved-objects-base-server-internal": + version "0.0.0" + uid "" + +"@kbn/core-saved-objects-base-server-mocks@link:bazel-bin/packages/core/saved-objects/core-saved-objects-base-server-mocks": + version "0.0.0" + uid "" + "@kbn/core-saved-objects-browser-internal@link:bazel-bin/packages/core/saved-objects/core-saved-objects-browser-internal": version "0.0.0" uid "" @@ -3397,6 +3405,10 @@ version "0.0.0" uid "" +"@kbn/core-saved-objects-utils-server@link:bazel-bin/packages/core/saved-objects/core-saved-objects-utils-server": + version "0.0.0" + uid "" + "@kbn/core-test-helpers-deprecations-getters@link:bazel-bin/packages/core/test-helpers/core-test-helpers-deprecations-getters": version "0.0.0" uid "" @@ -7347,6 +7359,14 @@ version "0.0.0" uid "" +"@types/kbn__core-saved-objects-base-server-internal@link:bazel-bin/packages/core/saved-objects/core-saved-objects-base-server-internal/npm_module_types": + version "0.0.0" + uid "" + +"@types/kbn__core-saved-objects-base-server-mocks@link:bazel-bin/packages/core/saved-objects/core-saved-objects-base-server-mocks/npm_module_types": + version "0.0.0" + uid "" + "@types/kbn__core-saved-objects-browser-internal@link:bazel-bin/packages/core/saved-objects/core-saved-objects-browser-internal/npm_module_types": version "0.0.0" uid "" @@ -7367,6 +7387,10 @@ version "0.0.0" uid "" +"@types/kbn__core-saved-objects-utils-server@link:bazel-bin/packages/core/saved-objects/core-saved-objects-utils-server/npm_module_types": + version "0.0.0" + uid "" + "@types/kbn__core-server-internal-base@link:bazel-bin/packages/core/server/internal-base/npm_module_types": version "0.0.0" uid ""