import fs from 'fs' ; import path from 'path' ; import { Sketch } from '..' ; import { AsyncTreeInputIterable , dedentSymbol , indentSymbol , printTree , } from './helpers/printTree' ; export default async function tree ( dirs , options ) { const depth = Number ( options . level || Infinity ) ; const printDescriptions = options . descriptions ; const tabWidth = Number ( options . tabWidth || 4 ) ; for ( const dir of dirs . length ? dirs : [ process . cwd ( ) ] ) { const iter = sketchTreeIter ( dir , { depth , printDescriptions } ) ; await printTree ( iter , tabWidth ) ; } } function sketchTreeIter ( file , { depth , printDescriptions } ) { return visit ( file , depth ) as AsyncTreeInputIterable < string > ; async function * visit ( file , depth ) { if ( fs . statSync ( file ) . isDirectory ( ) ) { yield * visitDir ( file , depth - 1 ) ; } else if ( await Sketch . isSketchFile ( file ) ) { const sketch = await Sketch . fromFile ( file ) ; yield * visitSketch ( sketch , depth - 1 ) ; } else { yield path . basename ( file ) ; } } async function * visitDir ( dir , depth ) { const { sketches , unassociatedFiles } = await Sketch . analyzeDirectory ( dir ) ; yield * [ '📁' + path . basename ( dir ) , indentSymbol ] ; if ( depth >= 0 ) { for ( const sketch of sketches . sort ( ( a , b ) => a . name . localeCompare ( b . name ) ) ) { yield * visitSketch ( sketch , depth - 1 ) ; } const files = [ ... unassociatedFiles ] . map ( f => path . join ( dir , f ) ) . sort ( ( a , b ) => a . localeCompare ( b ) ) . sort ( ( a , b ) => Number ( fs . statSync ( b ) . isDirectory ( ) ) - Number ( fs . statSync ( a ) . isDirectory ( ) ) ) ; for ( const file of files ) { yield * visit ( file , depth - 1 ) ; } } yield dedentSymbol ; } async function * visitSketch ( sketch , depth ) { const mainFile = sketch . files . length === 1 ? ` (${ sketch . mainFile })` : '' ; const description = printDescriptions && sketch . description ? ` - ${ sketch . description . replace ( /\s*\n\s*/g , ' ' ) }` : '' ; yield * [ '🎨' + `${ sketch . name }${ mainFile }${ description }` , indentSymbol ] ; if ( depth >= 0 && sketch . files . length > 1 ) { yield * sketch . files ; } yield dedentSymbol ; } }