import Boom from '@hapi/boom' ; import { createListStream } from '../../utils/streams' ; import { SavedObjectsClientContract , SavedObject } from '../types' ; import { fetchNestedDependencies } from './inject_nested_depdendencies' ; import { sortObjects } from './sort_objects' ; public export interface SavedObjectsExportOptions { /** optional array of saved object types. */ types ? : string [ ] ; /** optional array of objects to export. */ objects ? : Array < { /** the saved object id. */ id : string ; /** the saved object type. */ type : string ; } > ; /** optional query string to filter exported objects. */ search ? : string ; /** an instance of the SavedObjectsClient. */ savedObjectsClient : SavedObjectsClientContract ; /** the maximum number of objects to export. */ exportSizeLimit : number ; /** flag to also include all related saved objects in the export stream. */ includeReferencesDeep ? : boolean ; /** flag to not append  SavedObjectsExportResultDetails to the end of the export stream.  excludeExportDetails ? : boolean ; /** optional namespace to override the namespace used by the savedObjectsClient. */ namespace ? : string ; } public export interface SavedObjectsExportResultDetails { /** number of successfully exported objects */ exportedCount : number ; /** number of missing references */ missingRefCount : number ; /** missing references details */ missingReferences : Array < { /** the missing reference id. */ id : string ; /** the missing reference type. */ type : string ; } > ; } async function fetchObjectsToExport ( { objects , types , search , exportSizeLimit , savedObjectsClient , namespace , } ) { if ( ( types ?. length ?? 0 ) > 0 && ( objects ?. length ?? 0 ) > 0 ) { throw Boom . badRequest ( `Can't specify both "types" and "objects" properties when exporting` ) ; } if ( objects && objects . length > 0 ) { if ( objects . length > exportSizeLimit ) { throw Boom . badRequest ( `Can't export more than ${ exportSizeLimit } objects` ) ; } if ( typeof search === 'string' ) { throw Boom . badRequest ( `Can't specify both "search" and "objects" properties when exporting` ) ; } const bulkGetResult = await savedObjectsClient . bulkGet ( objects , { namespace } ) ; const erroredObjects = bulkGetResult . saved_objects . filter ( ( obj ) => ! ! obj . error ) ; if ( erroredObjects . length ) { const err = Boom . badRequest ( ) ; err . output . payload . attributes = { objects : erroredObjects , } ; throw err ; } return bulkGetResult . saved_objects ; } else if ( types && types . length > 0 ) { const findResponse = await savedObjectsClient . find ( { type : types , search , perPage : exportSizeLimit , namespaces : namespace ? [ namespace ] : undefined , } ) ; if ( findResponse . total > exportSizeLimit ) { throw Boom . badRequest ( `Can't export more than ${ exportSizeLimit } objects` ) ; } return ( findResponse . saved_objects . map ( ( { score , ... obj } ) => obj ) . sort ( ( a , b ) => ( a . id > b . id ? 1 : - 1 ) ) ) ; } else { throw Boom . badRequest ( 'Either `type` or `objects` are required.' ) ; } } /**
 * Generates sorted saved object stream to be used for export.
 * See the  SavedObjectsExportOptions for more detailed information.
 *
 *  public export async function exportSavedObjectsToStream ( { types , objects , search , savedObjectsClient , exportSizeLimit , includeReferencesDeep = false , excludeExportDetails = false , namespace , } ) { const rootObjects = await fetchObjectsToExport ( { types , objects , search , savedObjectsClient , exportSizeLimit , namespace , } ) ; let exportedObjects = [ ] ; let missingReferences = [ ] ; if ( includeReferencesDeep ) { const fetchResult = await fetchNestedDependencies ( rootObjects , savedObjectsClient , namespace ) ; exportedObjects = sortObjects ( fetchResult . objects ) ; missingReferences = fetchResult . missingRefs ; } else { exportedObjects = sortObjects ( rootObjects ) ; } const redactedObjects = exportedObjects . map < SavedObject < unknown > > ( ( { namespaces , ... object } ) => object ) ; const exportDetails = { exportedCount : exportedObjects . length , missingRefCount : missingReferences . length , missingReferences , } ; return createListStream ( [ ... redactedObjects , ... ( excludeExportDetails ? [ ] : [ exportDetails ] ) ] ) ; }