import Boom from '@hapi/boom' ; import { SavedObject } from '../types' ; export function sortObjects ( savedObjects ) { const path = new Set < SavedObject > ( ) ; const sorted = new Set < SavedObject > ( ) ; const objectsByTypeId = new Map ( savedObjects . map ( ( object ) => [ `${ object . type }:${ object . id }` , object ] as [ string , SavedObject ] ) ) ; function includeObjects ( objects ) { for ( const object of objects ) { if ( path . has ( object ) ) { throw Boom . badRequest ( `circular reference: ${ [ ... path , object ] . map ( ( obj ) => `[${ obj . type }:${ obj . id }]` ) . join ( ' ref-> ' ) }` ) ; } const refdObjects = object . references . map ( ( ref ) => objectsByTypeId . get ( `${ ref . type }:${ ref . id }` ) ) . filter ( ( ref ) : ref is SavedObject => ! ! ref ) ; if ( refdObjects . length ) { path . add ( object ) ; includeObjects ( refdObjects ) ; path . delete ( object ) ; } sorted . add ( object ) ; } } includeObjects ( savedObjects ) ; return [ ... sorted ] ; }