From 32f9866b634124b2bad59914a2fcce2ffa1b507f Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Thu, 11 May 2023 08:07:37 +0200 Subject: [PATCH] add left and right helpers --- .../src/lib/apis/bulk_create.ts | 75 ++++++++---------- .../src/lib/apis/bulk_delete.ts | 79 ++++++++----------- .../src/lib/apis/bulk_get.ts | 24 +++--- .../src/lib/apis/bulk_update.ts | 43 +++++----- .../src/lib/apis/check_conflicts.ts | 37 +++++---- .../apis/internals/internal_bulk_resolve.ts | 20 ++--- .../internals/preflight_check_for_create.ts | 13 +-- .../apis/internals/update_objects_spaces.ts | 34 +++----- .../src/lib/apis/utils/either.ts | 18 +++++ .../src/lib/apis/utils/index.ts | 2 +- 10 files changed, 160 insertions(+), 185 deletions(-) diff --git a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/bulk_create.ts b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/bulk_create.ts index 219e6071ce33..c7802397739c 100644 --- a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/bulk_create.ts +++ b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/bulk_create.ts @@ -27,6 +27,8 @@ import { getBulkOperationError, getCurrentTime, getExpectedVersionProperties, + left, + right, isLeft, isRight, normalizeNamespace, @@ -42,6 +44,15 @@ export interface PerformBulkCreateParams { options: SavedObjectsCreateOptions; } +type ExpectedResult = Either< + { type: string; id?: string; error: Payload }, + { + method: 'index' | 'create'; + object: SavedObjectsBulkCreateObject & { id: string }; + preflightCheckIndex?: number; + } +>; + export const performBulkCreate = async ( { objects, options }: PerformBulkCreateParams, { @@ -73,14 +84,6 @@ export const performBulkCreate = async ( const time = getCurrentTime(); let preflightCheckIndexCounter = 0; - type ExpectedResult = Either< - { type: string; id?: string; error: Payload }, - { - method: 'index' | 'create'; - object: SavedObjectsBulkCreateObject & { id: string }; - preflightCheckIndex?: number; - } - >; const expectedResults = objects.map((object) => { const { type, id: requestId, initialNamespaces, version, managed } = object; let error: DecoratedError | undefined; @@ -99,27 +102,21 @@ export const performBulkCreate = async ( } if (error) { - return { - tag: 'Left', - value: { id: requestId, type, error: errorContent(error) }, - }; + return left({ id: requestId, type, error: errorContent(error) }); } const method = requestId && overwrite ? 'index' : 'create'; const requiresNamespacesCheck = requestId && registry.isMultiNamespace(type); - return { - tag: 'Right', - value: { - method, - object: { - ...object, - id, - managed: setManaged({ optionsManaged, objectManaged }), - }, - ...(requiresNamespacesCheck && { preflightCheckIndex: preflightCheckIndexCounter++ }), + return right({ + method, + object: { + ...object, + id, + managed: setManaged({ optionsManaged, objectManaged }), }, - }; + ...(requiresNamespacesCheck && { preflightCheckIndex: preflightCheckIndexCounter++ }), + }) as ExpectedResult; }); const validObjects = expectedResults.filter(isRight); @@ -187,17 +184,14 @@ export const performBulkCreate = async ( const { type, id, existingDocument, error } = preflightResult; if (error) { const { metadata } = error; - return { - tag: 'Left', - value: { - id, - type, - error: { - ...errorContent(SavedObjectsErrorHelpers.createConflictError(type, id)), - ...(metadata && { metadata }), - }, + return left({ + id, + type, + error: { + ...errorContent(SavedObjectsErrorHelpers.createConflictError(type, id)), + ...(metadata && { metadata }), }, - }; + }); } savedObjectNamespaces = initialNamespaces || getSavedObjectNamespaces(namespace, existingDocument); @@ -249,14 +243,11 @@ export const performBulkCreate = async ( try { validationHelper.validateObjectForCreate(object.type, migrated); } catch (error) { - return { - tag: 'Left', - value: { - id: object.id, - type: object.type, - error, - }, - }; + return left({ + id: object.id, + type: object.type, + error, + }); } const expectedResult = { @@ -276,7 +267,7 @@ export const performBulkCreate = async ( expectedResult.rawMigratedDoc._source ); - return { tag: 'Right', value: expectedResult }; + return right(expectedResult); }) ); diff --git a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/bulk_delete.ts b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/bulk_delete.ts index db978199bbe7..768dcf91b61c 100644 --- a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/bulk_delete.ts +++ b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/bulk_delete.ts @@ -28,6 +28,8 @@ import { isMgetDoc, rawDocExistsInNamespace, isRight, + left, + right, } from './utils'; import type { ApiExecutionContext } from './types'; import { deleteLegacyUrlAliases } from '../legacy_url_aliases'; @@ -230,24 +232,18 @@ function presortObjectsByNamespaceType( return objects.map((object) => { const { type, id } = object; if (!allowedTypes.includes(type)) { - return { - tag: 'Left', - value: { - id, - type, - error: errorContent(SavedObjectsErrorHelpers.createUnsupportedTypeError(type)), - }, - }; + return left({ + id, + type, + error: errorContent(SavedObjectsErrorHelpers.createUnsupportedTypeError(type)), + }); } const requiresNamespacesCheck = registry.isMultiNamespace(type); - return { - tag: 'Right', - value: { - type, - id, - ...(requiresNamespacesCheck && { esRequestIndex: bulkGetRequestIndexCounter++ }), - }, - }; + return right({ + type, + id, + ...(requiresNamespacesCheck && { esRequestIndex: bulkGetRequestIndexCounter++ }), + }); }); } @@ -281,25 +277,19 @@ function getExpectedBulkDeleteMultiNamespaceDocsResults( // return an error if the doc isn't found at all or the doc doesn't exist in the namespaces if (!docFound) { - return { - tag: 'Left', - value: { - id, - type, - error: errorContent(SavedObjectsErrorHelpers.createGenericNotFoundError(type, id)), - }, - }; + return left({ + id, + type, + error: errorContent(SavedObjectsErrorHelpers.createGenericNotFoundError(type, id)), + }); } // the following check should be redundant since we're retrieving the docs from elasticsearch but we check just to make sure if (!rawDocExistsInNamespace(registry, actualResult as SavedObjectsRawDoc, namespace)) { - return { - tag: 'Left', - value: { - id, - type, - error: errorContent(SavedObjectsErrorHelpers.createGenericNotFoundError(type, id)), - }, - }; + return left({ + id, + type, + error: errorContent(SavedObjectsErrorHelpers.createGenericNotFoundError(type, id)), + }); } // @ts-expect-error MultiGetHit is incorrectly missing _id, _source namespaces = actualResult!._source.namespaces ?? [ @@ -308,19 +298,16 @@ function getExpectedBulkDeleteMultiNamespaceDocsResults( const useForce = force && force === true; // the document is shared to more than one space and can only be deleted by force. if (!useForce && (namespaces.length > 1 || namespaces.includes(ALL_NAMESPACES_STRING))) { - return { - tag: 'Left', - value: { - success: false, - id, - type, - error: errorContent( - SavedObjectsErrorHelpers.createBadRequestError( - 'Unable to delete saved object that exists in multiple namespaces, use the `force` option to delete it anyway' - ) - ), - }, - }; + return left({ + success: false, + id, + type, + error: errorContent( + SavedObjectsErrorHelpers.createBadRequestError( + 'Unable to delete saved object that exists in multiple namespaces, use the `force` option to delete it anyway' + ) + ), + }); } } // contains all objects that passed initial preflight checks, including single namespace objects that skipped the mget call @@ -332,7 +319,7 @@ function getExpectedBulkDeleteMultiNamespaceDocsResults( esRequestIndex: indexCounter++, }; - return { tag: 'Right', value: expectedResult }; + return right(expectedResult); }); return expectedBulkDeleteMultiNamespaceDocsResults; } diff --git a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/bulk_get.ts b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/bulk_get.ts index c10e81d0e3c9..19ac91083c8c 100644 --- a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/bulk_get.ts +++ b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/bulk_get.ts @@ -27,6 +27,8 @@ import { getSavedObjectFromSource, isLeft, isRight, + left, + right, rawDocExistsInNamespaces, } from './utils'; import { ApiExecutionContext } from './types'; @@ -93,26 +95,20 @@ export const performBulkGet = async ( } if (error) { - return { - tag: 'Left', - value: { id, type, error: errorContent(error) }, - }; + return left({ id, type, error: errorContent(error) }); } let namespaces = object.namespaces; if (spacesExtension && namespaces?.includes(ALL_NAMESPACES_STRING)) { namespaces = await getAvailableSpaces(); } - return { - tag: 'Right', - value: { - type, - id, - fields, - namespaces, - esRequestIndex: bulkGetRequestIndexCounter++, - }, - }; + return right({ + type, + id, + fields, + namespaces, + esRequestIndex: bulkGetRequestIndexCounter++, + }); }) ); diff --git a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/bulk_update.ts b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/bulk_update.ts index 5f6981152191..b9c0f10a9021 100644 --- a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/bulk_update.ts +++ b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/bulk_update.ts @@ -29,8 +29,10 @@ import { getBulkOperationError, getCurrentTime, getExpectedVersionProperties, - isLeft, isMgetDoc, + left, + right, + isLeft, isRight, rawDocExistsInNamespace, } from './utils'; @@ -80,10 +82,7 @@ export const performBulkUpdate = async ( } if (error) { - return { - tag: 'Left', - value: { id, type, error: errorContent(error) }, - }; + return left({ id, type, error: errorContent(error) }); } const documentToSave = { @@ -94,17 +93,14 @@ export const performBulkUpdate = async ( const requiresNamespacesCheck = registry.isMultiNamespace(object.type); - return { - tag: 'Right', - value: { - type, - id, - version, - documentToSave, - objectNamespace, - ...(requiresNamespacesCheck && { esRequestIndex: bulkGetRequestIndexCounter++ }), - }, - }; + return right({ + type, + id, + version, + documentToSave, + objectNamespace, + ...(requiresNamespacesCheck && { esRequestIndex: bulkGetRequestIndexCounter++ }), + }); }); const validObjects = expectedBulkGetResults.filter(isRight); @@ -199,14 +195,11 @@ export const performBulkUpdate = async ( getNamespaceId(objectNamespace) ) ) { - return { - tag: 'Left', - value: { - id, - type, - error: errorContent(SavedObjectsErrorHelpers.createGenericNotFoundError(type, id)), - }, - }; + return left({ + id, + type, + error: errorContent(SavedObjectsErrorHelpers.createGenericNotFoundError(type, id)), + }); } // @ts-expect-error MultiGetHit is incorrectly missing _id, _source namespaces = actualResult!._source.namespaces ?? [ @@ -251,7 +244,7 @@ export const performBulkUpdate = async ( } ); - return { tag: 'Right', value: expectedResult }; + return right(expectedResult); }) ); diff --git a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/check_conflicts.ts b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/check_conflicts.ts index b0f7b1bf38da..6f110c3d6f90 100644 --- a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/check_conflicts.ts +++ b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/check_conflicts.ts @@ -18,7 +18,16 @@ import { SavedObjectsBaseOptions, SavedObjectsCheckConflictsResponse, } from '@kbn/core-saved-objects-api-server'; -import { Either, errorContent, isLeft, isRight, isMgetDoc, rawDocExistsInNamespace } from './utils'; +import { + Either, + errorContent, + left, + right, + isLeft, + isRight, + isMgetDoc, + rawDocExistsInNamespace, +} from './utils'; import { ApiExecutionContext } from './types'; export interface PerformCheckConflictsParams { @@ -48,24 +57,18 @@ export const performCheckConflicts = async ( const { type, id } = object; if (!allowedTypes.includes(type)) { - return { - tag: 'Left', - value: { - id, - type, - error: errorContent(SavedObjectsErrorHelpers.createUnsupportedTypeError(type)), - }, - }; + return left({ + id, + type, + error: errorContent(SavedObjectsErrorHelpers.createUnsupportedTypeError(type)), + }); } - return { - tag: 'Right', - value: { - type, - id, - esRequestIndex: bulkGetRequestIndexCounter++, - }, - }; + return right({ + type, + id, + esRequestIndex: bulkGetRequestIndexCounter++, + }); }); const validObjects = expectedBulkGetResults.filter(isRight); diff --git a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/internals/internal_bulk_resolve.ts b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/internals/internal_bulk_resolve.ts index 7c1124f376f8..6e143004dfb3 100644 --- a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/internals/internal_bulk_resolve.ts +++ b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/internals/internal_bulk_resolve.ts @@ -45,6 +45,8 @@ import { type Right, isLeft, isRight, + left, + right, } from '../utils'; import type { RepositoryEsClient } from '../../repository_es_client'; @@ -271,19 +273,13 @@ function validateObjectTypes(objects: SavedObjectsBulkResolveObject[], allowedTy return objects.map>((object) => { const { type, id } = object; if (!allowedTypes.includes(type)) { - return { - tag: 'Left', - value: { - type, - id, - error: SavedObjectsErrorHelpers.createUnsupportedTypeError(type), - }, - }; + return left({ + type, + id, + error: SavedObjectsErrorHelpers.createUnsupportedTypeError(type), + }); } - return { - tag: 'Right', - value: object, - }; + return right(object); }); } diff --git a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/internals/preflight_check_for_create.ts b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/internals/preflight_check_for_create.ts index bc899adda83d..aec1ac9991d4 100644 --- a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/internals/preflight_check_for_create.ts +++ b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/internals/preflight_check_for_create.ts @@ -24,7 +24,7 @@ import { import { findLegacyUrlAliases } from '../../legacy_url_aliases'; import type { CreatePointInTimeFinderFn } from '../../point_in_time_finder'; import type { RepositoryEsClient } from '../../repository_es_client'; -import { isLeft, isRight, rawDocExistsInNamespaces, type Either } from '../utils'; +import { left, right, isLeft, isRight, rawDocExistsInNamespaces, type Either } from '../utils'; /** * If the object will be created in this many spaces (or "*" all current and future spaces), we use find to fetch all aliases. @@ -200,9 +200,10 @@ async function optionallyFindAliases( const objectsToGetOrObjectsToFind = objects.map>((object) => { const { type, id, namespaces, overwrite = false } = object; const spaces = new Set(namespaces); - const tag = - spaces.size > FIND_ALIASES_THRESHOLD || spaces.has(ALL_NAMESPACES_STRING) ? 'Right' : 'Left'; - return { tag, value: { type, id, overwrite, spaces } }; + const value = { type, id, overwrite, spaces }; + return spaces.size > FIND_ALIASES_THRESHOLD || spaces.has(ALL_NAMESPACES_STRING) + ? right(value) + : left(value); }); const objectsToFind = objectsToGetOrObjectsToFind @@ -235,13 +236,13 @@ async function optionallyFindAliases( } if (spacesWithConflictingAliases.length) { // we found one or more conflicting aliases, this is an error result - return { tag: 'Left', value: { ...either.value, spacesWithConflictingAliases } }; + return left({ ...either.value, spacesWithConflictingAliases }); } } // we checked for aliases but did not detect any conflicts; make sure we don't check for aliases again during mget checkAliases = false; } - return { tag: 'Right', value: { ...either.value, checkAliases } }; + return right({ ...either.value, checkAliases }); }); return result; diff --git a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/internals/update_objects_spaces.ts b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/internals/update_objects_spaces.ts index 9cdc7fe1b9ef..62b006cc0d9a 100644 --- a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/internals/update_objects_spaces.ts +++ b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/internals/update_objects_spaces.ts @@ -36,6 +36,8 @@ import { type Either, isLeft, isRight, + left, + right, } from '../utils'; import { DEFAULT_REFRESH_SETTING } from '../../constants'; import type { RepositoryEsClient } from '../../repository_es_client'; @@ -117,10 +119,7 @@ export async function updateObjectsSpaces({ if (!allowedTypes.includes(type)) { const error = errorContent(SavedObjectsErrorHelpers.createGenericNotFoundError(type, id)); - return { - tag: 'Left', - value: { id, type, spaces: [], error }, - }; + return left({ id, type, spaces: [], error }); } if (!registry.isShareable(type)) { const error = errorContent( @@ -128,21 +127,15 @@ export async function updateObjectsSpaces({ `${type} doesn't support multiple namespaces` ) ); - return { - tag: 'Left', - value: { id, type, spaces: [], error }, - }; + return left({ id, type, spaces: [], error }); } - return { - tag: 'Right', - value: { - type, - id, - version, - esRequestIndex: bulkGetRequestIndexCounter++, - }, - }; + return right({ + type, + id, + version, + esRequestIndex: bulkGetRequestIndexCounter++, + }); }); const validObjects = expectedBulkGetResults.filter(isRight); @@ -217,10 +210,7 @@ export async function updateObjectsSpaces({ !rawDocExistsInNamespace(registry, doc, namespace) ) { const error = errorContent(SavedObjectsErrorHelpers.createGenericNotFoundError(type, id)); - return { - tag: 'Left', - value: { id, type, spaces: [], error }, - }; + return left({ id, type, spaces: [], error }); } const currentSpaces = doc._source?.namespaces ?? []; @@ -265,7 +255,7 @@ export async function updateObjectsSpaces({ } } - return { tag: 'Right', value: expectedResult }; + return right(expectedResult); }); const { refresh = DEFAULT_REFRESH_SETTING } = options; diff --git a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/utils/either.ts b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/utils/either.ts index e573ea87ce6d..9403945a9a65 100644 --- a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/utils/either.ts +++ b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/utils/either.ts @@ -30,6 +30,24 @@ export interface Right { value: R; } +/** + * Returns a {@link Left} part holding the provided value. + * @internal + */ +export const left = (value: L): Left => ({ + tag: 'Left', + value, +}); + +/** + * Returns a {@link Right} part holding the provided value. + * @internal + */ +export const right = (value: R): Right => ({ + tag: 'Right', + value, +}); + /** * Type guard for left part of discriminated union ({@link Left}, {@link Either}). * @internal diff --git a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/utils/index.ts b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/utils/index.ts index db96a742b2bb..f3562dffb1e8 100644 --- a/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/utils/index.ts +++ b/packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/apis/utils/index.ts @@ -22,4 +22,4 @@ export { getSavedObjectNamespaces, type GetSavedObjectFromSourceOptions, } from './internal_utils'; -export { type Left, type Either, type Right, isLeft, isRight } from './either'; +export { type Left, type Either, type Right, isLeft, isRight, left, right } from './either';