From fa6ae1cd736a3de905ec68dec7b51077e45a12f1 Mon Sep 17 00:00:00 2001 From: Joe Portner <5295965+jportner@users.noreply.github.com> Date: Wed, 19 Aug 2020 14:30:26 -0400 Subject: [PATCH] Add `namespaceStringToId` and `namespaceIdToString` methods to core Now that saved objects' `namespaces` are exposed, we should provide a method to compare these strings to namespace IDs. The Spaces plugin already provided utility functions for this; I changed them to be a facade over the new core functions. The reason for this is that other plugins (alerting, actions) depend on the Spaces plugin and will use an `undefined` namespace if the Spaces plugin is not enabled. --- .../core/server/kibana-plugin-core-server.md | 2 + ...-plugin-core-server.namespaceidtostring.md | 13 +++++ ...-plugin-core-server.namespacestringtoid.md | 13 +++++ src/core/server/index.ts | 2 + .../server/saved_objects/service/index.ts | 2 + .../server/saved_objects/service/lib/index.ts | 2 + .../service/lib/namespace.test.ts | 53 +++++++++++++++++++ .../saved_objects/service/lib/namespace.ts | 50 +++++++++++++++++ .../saved_objects/service/lib/repository.ts | 29 ++++------ .../service/lib/search_dsl/query_params.ts | 11 ++-- src/core/server/server.api.md | 6 +++ .../lib/copy_to_spaces/copy_to_spaces.test.ts | 1 + .../resolve_copy_conflicts.test.ts | 1 + .../server/lib/utils/__mocks__/index.ts | 14 +++++ .../spaces/server/lib/utils/namespace.test.ts | 46 ++++++---------- .../spaces/server/lib/utils/namespace.ts | 36 ++++++------- .../routes/api/external/copy_to_space.test.ts | 2 +- 17 files changed, 206 insertions(+), 77 deletions(-) create mode 100644 docs/development/core/server/kibana-plugin-core-server.namespaceidtostring.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.namespacestringtoid.md create mode 100644 src/core/server/saved_objects/service/lib/namespace.test.ts create mode 100644 src/core/server/saved_objects/service/lib/namespace.ts create mode 100644 x-pack/plugins/spaces/server/lib/utils/__mocks__/index.ts diff --git a/docs/development/core/server/kibana-plugin-core-server.md b/docs/development/core/server/kibana-plugin-core-server.md index 5347f0b55e19b..5098e60ef6785 100644 --- a/docs/development/core/server/kibana-plugin-core-server.md +++ b/docs/development/core/server/kibana-plugin-core-server.md @@ -219,6 +219,8 @@ The plugin integrates with the core system via lifecycle events: `setup` | Variable | Description | | --- | --- | | [kibanaResponseFactory](./kibana-plugin-core-server.kibanaresponsefactory.md) | Set of helpers used to create KibanaResponse to form HTTP response on an incoming request. Should be returned as a result of [RequestHandler](./kibana-plugin-core-server.requesthandler.md) execution. | +| [namespaceIdToString](./kibana-plugin-core-server.namespaceidtostring.md) | Converts a given saved object namespace ID to its string representation. All namespace IDs have an identical string representation, with the exception of the undefined namespace ID (which has a namespace string of 'default'). | +| [namespaceStringToId](./kibana-plugin-core-server.namespacestringtoid.md) | Converts a given saved object namespace string to its ID representation. All namespace strings have an identical ID representation, with the exception of the 'default' namespace string (which has a namespace ID of undefined). | | [ServiceStatusLevels](./kibana-plugin-core-server.servicestatuslevels.md) | The current "level" of availability of a service. | | [validBodyOutput](./kibana-plugin-core-server.validbodyoutput.md) | The set of valid body.output | diff --git a/docs/development/core/server/kibana-plugin-core-server.namespaceidtostring.md b/docs/development/core/server/kibana-plugin-core-server.namespaceidtostring.md new file mode 100644 index 0000000000000..5c9f093531e1c --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.namespaceidtostring.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [namespaceIdToString](./kibana-plugin-core-server.namespaceidtostring.md) + +## namespaceIdToString variable + +Converts a given saved object namespace ID to its string representation. All namespace IDs have an identical string representation, with the exception of the `undefined` namespace ID (which has a namespace string of `'default'`). + +Signature: + +```typescript +namespaceIdToString: (namespace?: string | undefined) => string +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.namespacestringtoid.md b/docs/development/core/server/kibana-plugin-core-server.namespacestringtoid.md new file mode 100644 index 0000000000000..39d6a13aa7fb0 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.namespacestringtoid.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [namespaceStringToId](./kibana-plugin-core-server.namespacestringtoid.md) + +## namespaceStringToId variable + +Converts a given saved object namespace string to its ID representation. All namespace strings have an identical ID representation, with the exception of the `'default'` namespace string (which has a namespace ID of `undefined`). + +Signature: + +```typescript +namespaceStringToId: (namespace: string) => string | undefined +``` diff --git a/src/core/server/index.ts b/src/core/server/index.ts index 382318ea86a34..de45f0a665906 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -298,6 +298,8 @@ export { exportSavedObjectsToStream, importSavedObjectsFromStream, resolveSavedObjectsImportErrors, + namespaceIdToString, + namespaceStringToId, } from './saved_objects'; export { diff --git a/src/core/server/saved_objects/service/index.ts b/src/core/server/saved_objects/service/index.ts index 9f625b4732e26..245df328db665 100644 --- a/src/core/server/saved_objects/service/index.ts +++ b/src/core/server/saved_objects/service/index.ts @@ -58,6 +58,8 @@ export { SavedObjectsErrorHelpers, SavedObjectsClientFactory, SavedObjectsClientFactoryProvider, + namespaceIdToString, + namespaceStringToId, } from './lib'; export * from './saved_objects_client'; diff --git a/src/core/server/saved_objects/service/lib/index.ts b/src/core/server/saved_objects/service/lib/index.ts index e103120388e35..cfae6ae9b62d5 100644 --- a/src/core/server/saved_objects/service/lib/index.ts +++ b/src/core/server/saved_objects/service/lib/index.ts @@ -30,3 +30,5 @@ export { } from './scoped_client_provider'; export { SavedObjectsErrorHelpers } from './errors'; + +export { namespaceIdToString, namespaceStringToId } from './namespace'; diff --git a/src/core/server/saved_objects/service/lib/namespace.test.ts b/src/core/server/saved_objects/service/lib/namespace.test.ts new file mode 100644 index 0000000000000..c5818deb8ef2a --- /dev/null +++ b/src/core/server/saved_objects/service/lib/namespace.test.ts @@ -0,0 +1,53 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { namespaceIdToString, namespaceStringToId } from './namespace'; + +describe('#namespaceIdToString', () => { + it('converts `undefined` to default namespace string', () => { + expect(namespaceIdToString(undefined)).toEqual('default'); + }); + + it('leaves other namespace IDs as-is', () => { + expect(namespaceIdToString('foo')).toEqual('foo'); + }); + + it('throws an error when a namespace ID is an empty string', () => { + expect(() => namespaceIdToString('')).toThrowError('namespace cannot be an empty string'); + }); +}); + +describe('#namespaceStringToId', () => { + it('converts default namespace string to `undefined`', () => { + expect(namespaceStringToId('default')).toBeUndefined(); + }); + + it('leaves other namespace strings as-is', () => { + expect(namespaceStringToId('foo')).toEqual('foo'); + }); + + it('throws an error when a namespace string is falsy', () => { + const test = (arg: any) => + expect(() => namespaceStringToId(arg)).toThrowError('namespace must be a non-empty string'); + + test(undefined); + test(null); + test(''); + }); +}); diff --git a/src/core/server/saved_objects/service/lib/namespace.ts b/src/core/server/saved_objects/service/lib/namespace.ts new file mode 100644 index 0000000000000..385725ca6e948 --- /dev/null +++ b/src/core/server/saved_objects/service/lib/namespace.ts @@ -0,0 +1,50 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const DEFAULT_NAMESPACE_STRING = 'default'; + +/** + * @public + * Converts a given saved object namespace ID to its string representation. All namespace IDs have an identical string representation, with + * the exception of the `undefined` namespace ID (which has a namespace string of `'default'`). + * + * @param namespace The namespace ID, which must be either a non-empty string or `undefined`. + */ +export const namespaceIdToString = (namespace?: string) => { + if (namespace === '') { + throw new TypeError('namespace cannot be an empty string'); + } + + return namespace ?? DEFAULT_NAMESPACE_STRING; +}; + +/** + * @public + * Converts a given saved object namespace string to its ID representation. All namespace strings have an identical ID representation, with + * the exception of the `'default'` namespace string (which has a namespace ID of `undefined`). + * + * @param namespace The namespace string, which must be non-empty. + */ +export const namespaceStringToId = (namespace: string) => { + if (!namespace) { + throw new TypeError('namespace must be a non-empty string'); + } + + return namespace !== DEFAULT_NAMESPACE_STRING ? namespace : undefined; +}; diff --git a/src/core/server/saved_objects/service/lib/repository.ts b/src/core/server/saved_objects/service/lib/repository.ts index 9f6db446ea195..941488d2264e6 100644 --- a/src/core/server/saved_objects/service/lib/repository.ts +++ b/src/core/server/saved_objects/service/lib/repository.ts @@ -63,6 +63,7 @@ import { } from '../../types'; import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry'; import { validateConvertFilterToKueryNode } from './filter_utils'; +import { namespaceIdToString } from './namespace'; // BEWARE: The SavedObjectClient depends on the implementation details of the SavedObjectsRepository // so any breaking changes to this repository are considered breaking changes to the SavedObjectsClient. @@ -470,7 +471,7 @@ export class SavedObjectsRepository { preflightResult = await this.preflightCheckIncludesNamespace(type, id, namespace); const existingNamespaces = getSavedObjectNamespaces(undefined, preflightResult); const remainingNamespaces = existingNamespaces?.filter( - (x) => x !== getNamespaceString(namespace) + (x) => x !== namespaceIdToString(namespace) ); if (remainingNamespaces?.length) { @@ -568,7 +569,7 @@ export class SavedObjectsRepository { } `, lang: 'painless', - params: { namespace: getNamespaceString(namespace) }, + params: { namespace: namespaceIdToString(namespace) }, }, conflicts: 'proceed', ...getSearchDsl(this._mappings, this._registry, { @@ -793,7 +794,7 @@ export class SavedObjectsRepository { let namespaces = []; if (!this._registry.isNamespaceAgnostic(type)) { - namespaces = doc._source.namespaces ?? [getNamespaceString(doc._source.namespace)]; + namespaces = doc._source.namespaces ?? [namespaceIdToString(doc._source.namespace)]; } return { @@ -849,7 +850,7 @@ export class SavedObjectsRepository { let namespaces: string[] = []; if (!this._registry.isNamespaceAgnostic(type)) { - namespaces = body._source.namespaces ?? [getNamespaceString(body._source.namespace)]; + namespaces = body._source.namespaces ?? [namespaceIdToString(body._source.namespace)]; } return { @@ -922,7 +923,7 @@ export class SavedObjectsRepository { let namespaces = []; if (!this._registry.isNamespaceAgnostic(type)) { - namespaces = body.get._source.namespaces ?? [getNamespaceString(body.get._source.namespace)]; + namespaces = body.get._source.namespaces ?? [namespaceIdToString(body.get._source.namespace)]; } return { @@ -1199,12 +1200,12 @@ export class SavedObjectsRepository { }; } namespaces = actualResult._source.namespaces ?? [ - getNamespaceString(actualResult._source.namespace), + namespaceIdToString(actualResult._source.namespace), ]; versionProperties = getExpectedVersionProperties(version, actualResult); } else { if (this._registry.isSingleNamespace(type)) { - namespaces = [getNamespaceString(namespace)]; + namespaces = [namespaceIdToString(namespace)]; } versionProperties = getExpectedVersionProperties(version); } @@ -1391,7 +1392,7 @@ export class SavedObjectsRepository { const savedObject = this._serializer.rawToSavedObject(raw); const { namespace, type } = savedObject; if (this._registry.isSingleNamespace(type)) { - savedObject.namespaces = [getNamespaceString(namespace)]; + savedObject.namespaces = [namespaceIdToString(namespace)]; } return omit(savedObject, 'namespace') as SavedObject; } @@ -1414,7 +1415,7 @@ export class SavedObjectsRepository { } const namespaces = raw._source.namespaces; - return namespaces?.includes(getNamespaceString(namespace)) ?? false; + return namespaces?.includes(namespaceIdToString(namespace)) ?? false; } /** @@ -1519,14 +1520,6 @@ function getExpectedVersionProperties(version?: string, document?: SavedObjectsR return {}; } -/** - * Returns the string representation of a namespace. - * The default namespace is undefined, and is represented by the string 'default'. - */ -function getNamespaceString(namespace?: string) { - return namespace ?? 'default'; -} - /** * Returns a string array of namespaces for a given saved object. If the saved object is undefined, the result is an array that contains the * current namespace. Value may be undefined if an existing saved object has no namespaces attribute; this should not happen in normal @@ -1542,7 +1535,7 @@ function getSavedObjectNamespaces( if (document) { return document._source?.namespaces; } - return [getNamespaceString(namespace)]; + return [namespaceIdToString(namespace)]; } const unique = (array: string[]) => [...new Set(array)]; 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 164756f9796a5..f945fc7925ac6 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 @@ -21,6 +21,7 @@ import { esKuery, KueryNode } from '../../../../../../plugins/data/server'; import { getRootPropertiesObjects, IndexMapping } from '../../../mappings'; import { ISavedObjectTypeRegistry } from '../../../saved_objects_type_registry'; +import { DEFAULT_NAMESPACE_STRING } from '../namespace'; /** * Gets the types based on the type. Uses mappings to support @@ -63,7 +64,7 @@ function getFieldsForTypes(types: string[], searchFields?: string[]) { */ function getClauseForType( registry: ISavedObjectTypeRegistry, - namespaces: string[] = ['default'], + namespaces: string[] = [DEFAULT_NAMESPACE_STRING], type: string ) { if (namespaces.length === 0) { @@ -78,11 +79,11 @@ function getClauseForType( }; } else if (registry.isSingleNamespace(type)) { const should: Array> = []; - const eligibleNamespaces = namespaces.filter((namespace) => namespace !== 'default'); + const eligibleNamespaces = namespaces.filter((x) => x !== DEFAULT_NAMESPACE_STRING); if (eligibleNamespaces.length > 0) { should.push({ terms: { namespace: eligibleNamespaces } }); } - if (namespaces.includes('default')) { + if (namespaces.includes(DEFAULT_NAMESPACE_STRING)) { should.push({ bool: { must_not: [{ exists: { field: 'namespace' } }] } }); } if (should.length === 0) { @@ -150,9 +151,7 @@ export function getQueryParams({ // would result in no results being returned, as the wildcard is treated as a literal, and not _actually_ as a wildcard. // We had a good discussion around the tradeoffs here: https://github.com/elastic/kibana/pull/67644#discussion_r441055716 const normalizedNamespaces = namespaces - ? Array.from( - new Set(namespaces.map((namespace) => (namespace === '*' ? 'default' : namespace))) - ) + ? Array.from(new Set(namespaces.map((x) => (x === '*' ? DEFAULT_NAMESPACE_STRING : x)))) : undefined; const bool: any = { diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 01558c1460f1b..da28ca3c3d53f 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -1597,6 +1597,12 @@ export function modifyUrl(url: string, urlModifier: (urlParts: URLMeaningfulPart // @public export type MutatingOperationRefreshSetting = boolean | 'wait_for'; +// @public +export const namespaceIdToString: (namespace?: string | undefined) => string; + +// @public +export const namespaceStringToId: (namespace: string) => string | undefined; + // Warning: (ae-missing-release-tag) "NodesVersionCompatibility" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) diff --git a/x-pack/plugins/spaces/server/lib/copy_to_spaces/copy_to_spaces.test.ts b/x-pack/plugins/spaces/server/lib/copy_to_spaces/copy_to_spaces.test.ts index 9679dd8c52523..6f30dade29e65 100644 --- a/x-pack/plugins/spaces/server/lib/copy_to_spaces/copy_to_spaces.test.ts +++ b/x-pack/plugins/spaces/server/lib/copy_to_spaces/copy_to_spaces.test.ts @@ -14,6 +14,7 @@ import { coreMock, savedObjectsTypeRegistryMock, httpServerMock } from 'src/core jest.mock('../../../../../../src/core/server', () => { return { + ...(jest.requireActual('../../../../../../src/core/server') as Record), exportSavedObjectsToStream: jest.fn(), importSavedObjectsFromStream: jest.fn(), }; diff --git a/x-pack/plugins/spaces/server/lib/copy_to_spaces/resolve_copy_conflicts.test.ts b/x-pack/plugins/spaces/server/lib/copy_to_spaces/resolve_copy_conflicts.test.ts index 7bb4c61ed51a0..139ca4c45ffb4 100644 --- a/x-pack/plugins/spaces/server/lib/copy_to_spaces/resolve_copy_conflicts.test.ts +++ b/x-pack/plugins/spaces/server/lib/copy_to_spaces/resolve_copy_conflicts.test.ts @@ -14,6 +14,7 @@ import { resolveCopySavedObjectsToSpacesConflictsFactory } from './resolve_copy_ jest.mock('../../../../../../src/core/server', () => { return { + ...(jest.requireActual('../../../../../../src/core/server') as Record), exportSavedObjectsToStream: jest.fn(), resolveSavedObjectsImportErrors: jest.fn(), }; diff --git a/x-pack/plugins/spaces/server/lib/utils/__mocks__/index.ts b/x-pack/plugins/spaces/server/lib/utils/__mocks__/index.ts new file mode 100644 index 0000000000000..2bb23d0304858 --- /dev/null +++ b/x-pack/plugins/spaces/server/lib/utils/__mocks__/index.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +const mockNamespaceIdToString = jest.fn(); +const mockNamespaceStringToId = jest.fn(); +jest.mock('../../../../../../../src/core/server', () => ({ + namespaceIdToString: mockNamespaceIdToString, + namespaceStringToId: mockNamespaceStringToId, +})); + +export { mockNamespaceIdToString, mockNamespaceStringToId }; diff --git a/x-pack/plugins/spaces/server/lib/utils/namespace.test.ts b/x-pack/plugins/spaces/server/lib/utils/namespace.test.ts index a81a5f3cee187..79d3dda301045 100644 --- a/x-pack/plugins/spaces/server/lib/utils/namespace.test.ts +++ b/x-pack/plugins/spaces/server/lib/utils/namespace.test.ts @@ -4,45 +4,29 @@ * you may not use this file except in compliance with the Elastic License. */ -import { DEFAULT_SPACE_ID } from '../../../common/constants'; +import { mockNamespaceIdToString, mockNamespaceStringToId } from './__mocks__'; import { spaceIdToNamespace, namespaceToSpaceId } from './namespace'; -describe('#spaceIdToNamespace', () => { - it('converts the default space to undefined', () => { - expect(spaceIdToNamespace(DEFAULT_SPACE_ID)).toBeUndefined(); - }); - - it('returns non-default spaces as-is', () => { - expect(spaceIdToNamespace('foo')).toEqual('foo'); - }); - - it('throws an error when a spaceId is not provided', () => { - // @ts-ignore ts knows this isn't right - expect(() => spaceIdToNamespace()).toThrowErrorMatchingInlineSnapshot(`"spaceId is required"`); +beforeEach(() => { + jest.clearAllMocks(); +}); - // @ts-ignore ts knows this isn't right - expect(() => spaceIdToNamespace(null)).toThrowErrorMatchingInlineSnapshot( - `"spaceId is required"` - ); +describe('#spaceIdToNamespace', () => { + it('returns result of namespaceStringToId', () => { + mockNamespaceStringToId.mockReturnValue('bar'); - expect(() => spaceIdToNamespace('')).toThrowErrorMatchingInlineSnapshot( - `"spaceId is required"` - ); + const result = spaceIdToNamespace('foo'); + expect(mockNamespaceStringToId).toHaveBeenCalledWith('foo'); + expect(result).toEqual('bar'); }); }); describe('#namespaceToSpaceId', () => { - it('returns the default space id for undefined namespaces', () => { - expect(namespaceToSpaceId(undefined)).toEqual(DEFAULT_SPACE_ID); - }); - - it('returns all other namespaces as-is', () => { - expect(namespaceToSpaceId('foo')).toEqual('foo'); - }); + it('returns result of namespaceIdToString', () => { + mockNamespaceIdToString.mockReturnValue('bar'); - it('throws an error when an empty string is provided', () => { - expect(() => namespaceToSpaceId('')).toThrowErrorMatchingInlineSnapshot( - `"namespace cannot be an empty string"` - ); + const result = namespaceToSpaceId('foo'); + expect(mockNamespaceIdToString).toHaveBeenCalledWith('foo'); + expect(result).toEqual('bar'); }); }); diff --git a/x-pack/plugins/spaces/server/lib/utils/namespace.ts b/x-pack/plugins/spaces/server/lib/utils/namespace.ts index 8c7ed2ea1797d..6861d0141ea02 100644 --- a/x-pack/plugins/spaces/server/lib/utils/namespace.ts +++ b/x-pack/plugins/spaces/server/lib/utils/namespace.ts @@ -4,28 +4,22 @@ * you may not use this file except in compliance with the Elastic License. */ -import { DEFAULT_SPACE_ID } from '../../../common/constants'; +import { namespaceStringToId, namespaceIdToString } from '../../../../../../src/core/server'; -export function spaceIdToNamespace(spaceId: string): string | undefined { - if (!spaceId) { - throw new TypeError('spaceId is required'); - } - - if (spaceId === DEFAULT_SPACE_ID) { - return undefined; - } - - return spaceId; +/** + * Converts a Space ID string to its namespace ID representation. Note that a Space ID string is equivalent to a namespace string. + * + * See also: {@link namespaceStringToId}. + */ +export function spaceIdToNamespace(spaceId: string) { + return namespaceStringToId(spaceId); } -export function namespaceToSpaceId(namespace: string | undefined): string { - if (namespace === '') { - throw new TypeError('namespace cannot be an empty string'); - } - - if (!namespace) { - return DEFAULT_SPACE_ID; - } - - return namespace; +/** + * Converts a namespace ID to its Space ID string representation. Note that a Space ID string is equivalent to a namespace string. + * + * See also: {@link namespaceIdToString}. + */ +export function namespaceToSpaceId(namespace?: string) { + return namespaceIdToString(namespace); } diff --git a/x-pack/plugins/spaces/server/routes/api/external/copy_to_space.test.ts b/x-pack/plugins/spaces/server/routes/api/external/copy_to_space.test.ts index b604554cbc59a..180507c22ffd5 100644 --- a/x-pack/plugins/spaces/server/routes/api/external/copy_to_space.test.ts +++ b/x-pack/plugins/spaces/server/routes/api/external/copy_to_space.test.ts @@ -30,10 +30,10 @@ import { securityMock } from '../../../../../security/server/mocks'; import { ObjectType } from '@kbn/config-schema'; jest.mock('../../../../../../../src/core/server', () => { return { + ...(jest.requireActual('../../../../../../../src/core/server') as Record), exportSavedObjectsToStream: jest.fn(), importSavedObjectsFromStream: jest.fn(), resolveSavedObjectsImportErrors: jest.fn(), - kibanaResponseFactory: jest.requireActual('src/core/server').kibanaResponseFactory, }; }); import {