import * as path from 'path' ; import * as fs from 'fs' ; const reAbsolutePosix = /^\/+/ ; const reAbsoluteWin32 = /^\\+/ ; const reAbsolute = path . sep === '/' ? reAbsolutePosix : reAbsoluteWin32 ; param basePath param filePath export function locateFile ( base , filePath ) { if ( /^\w+:/ . test ( filePath ) ) { return Promise . resolve ( filePath ) ; } filePath = path . normalize ( filePath ) ; return reAbsolute . test ( filePath ) ? resolveAbsolute ( base , filePath ) : resolveRelative ( base , filePath ) ; } /**
 * Resolves relative file path
 */ function resolveRelative ( basePath , filePath ) { return tryFile ( path . resolve ( basePath , filePath ) ) ; } /**
 * Resolves absolute file path agaist given editor: tries to find file in every
 * parent of editor’s file
 */ function resolveAbsolute ( basePath , filePath ) { return new Promise ( ( resolve , reject ) => { filePath = filePath . replace ( reAbsolute , '' ) ; const next = ( ctx ) => { tryFile ( path . resolve ( ctx , filePath ) ) . then ( resolve , ( ) => { const dir = path . dirname ( ctx ) ; if ( ! dir || dir === ctx ) { return reject ( `Unable to locate absolute file ${ filePath }` ) ; } next ( dir ) ; } ) ; } ; next ( basePath ) ; } ) ; } /**
 * Check if given file exists and it’s a file, not directory
 */ function tryFile ( file ) { return new Promise ( ( resolve , reject ) => { fs . stat ( file , ( err , stat ) => { if ( err ) { return reject ( err ) ; } if ( ! stat . isFile ( ) ) { return reject ( new Error ( `${ file } is not a file` ) ) ; } resolve ( file ) ; } ) ; } ) ; }