import { DepGraph } from 'dependency-graph' ; name description param { Array | Object } items param { string } afterProp param { string } beforeProp param { string } nameProp return { Array } export function sortByDependency < T > ( items , afterProp ? , beforeProp ? , nameProp = 'name' ) { const map = { } ; const depGraph = new DepGraph ( ) ; function addDependencies ( item , dependencyProp , addBefore = false ) { if ( dependencyProp && item [ dependencyProp ] ) { if ( ! Array . isArray ( item [ dependencyProp ] ) ) { throw new Error ( 'Error in item "' + item [ nameProp ] + '" - ' + dependencyProp + ' must be an array' ) ; } item [ dependencyProp ] . forEach ( dependency => { if ( ! map [ dependency ] ) { throw new Error ( 'Missing dependency: "' + dependency + '"  on "' + item [ nameProp ] + '"' ) ; } if ( addBefore ) { depGraph . addDependency ( dependency , item [ nameProp ] ) ; } else { depGraph . addDependency ( item [ nameProp ] , dependency ) ; } } ) ; } } Object . keys ( items ) . forEach ( itemKey => { const item = items [ itemKey ] ; if ( ! item [ nameProp ] ) { throw new Error ( 'Missing ' + nameProp + ' property on item ' + itemKey ) ; } map [ item [ nameProp ] ] = item ; depGraph . addNode ( item [ nameProp ] ) ; } ) ; Object . values ( items ) . forEach ( item => { addDependencies ( item , afterProp ) ; addDependencies ( item , beforeProp , true ) ; } ) ; return depGraph . overallOrder ( ) . map ( itemName => map [ itemName ] ) ; } ;