'use strict' ; import * as fs from 'fs' ; import * as glob from 'glob' ; import * as _ from 'lodash' ; import autobind from 'autobind-decorator' ; @ autobind export class FileMatcher { constructor ( public basePath , public extensions ) { } matchFiles ( includePaths ) { const expandedIncludePaths = _ . flatten ( includePaths . map ( ( path ) => glob . sync ( `${ this . basePath }${ path }` ) ) ) ; const [ directories , files ] = _ . partition ( expandedIncludePaths , ( file ) => fs . lstatSync ( file ) . isDirectory ( ) ) ; return _ . chain ( directories ) . map ( ( directory ) => glob . sync ( `${ directory }/**/**` ) ) . flatMap ( this . prunePathsWithinSymlinks ) . concat ( files ) . filter ( this . isFileWithMatchingExtension ) . value ( ) as string [ ] ; } private prunePathsWithinSymlinks ( paths ) { const symlinks = paths . filter ( ( path ) => fs . lstatSync ( path ) . isSymbolicLink ( ) ) ; return paths . filter ( ( path ) => symlinks . every ( ( symlink ) => path . indexOf ( symlink ) !== 0 ) ) ; } private isFileWithMatchingExtension ( file ) { const stats = fs . lstatSync ( file ) ; const extension = '.' + file . split ( '.' ) . pop ( ) ; return ( stats . isFile ( ) && ! stats . isSymbolicLink ( ) && this . extensions . indexOf ( extension ) >= 0 ) ; } }