import path from 'path' ; import { ExplorerBase } from './ExplorerBase' ; import { readFile } from './readFile' ; import { cacheWrapper } from './cacheWrapper' ; import { getDirectory } from './getDirectory' ; import { CosmiconfigResult , ExplorerOptions , LoadedFileContent } from './types' ; class Explorer extends ExplorerBase < ExplorerOptions > { public constructor ( options ) { super ( options ) ; } public async search ( searchFrom = process . cwd ( ) ) { const startDirectory = await getDirectory ( searchFrom ) ; const result = await this . searchFromDirectory ( startDirectory ) ; return result ; } private async searchFromDirectory ( dir ) { const absoluteDir = path . resolve ( process . cwd ( ) , dir ) ; const run = async ( ) : Promise < CosmiconfigResult > => { const result = await this . searchDirectory ( absoluteDir ) ; const nextDir = this . nextDirectoryToSearch ( absoluteDir , result ) ; if ( nextDir ) { return this . searchFromDirectory ( nextDir ) ; } const transformResult = await this . config . transform ( result ) ; return transformResult ; } ; if ( this . searchCache ) { return cacheWrapper ( this . searchCache , absoluteDir , run ) ; } return run ( ) ; } private async searchDirectory ( dir ) { for await ( const place of this . config . searchPlaces ) { const placeResult = await this . loadSearchPlace ( dir , place ) ; if ( this . shouldSearchStopWithResult ( placeResult ) === true ) { return placeResult ; } } return null ; } private async loadSearchPlace ( dir , place ) { const filepath = path . join ( dir , place ) ; const fileContents = await readFile ( filepath ) ; const result = await this . createCosmiconfigResult ( filepath , fileContents ) ; return result ; } private async loadFileContent ( filepath , content ) { if ( content === null ) { return null ; } if ( content . trim ( ) === '' ) { return undefined ; } const loader = this . getLoaderEntryForFile ( filepath ) ; const loaderResult = await loader ( filepath , content ) ; return loaderResult ; } private async createCosmiconfigResult ( filepath , content ) { const fileContent = await this . loadFileContent ( filepath , content ) ; const result = this . loadedContentToCosmiconfigResult ( filepath , fileContent ) ; return result ; } public async load ( filepath ) { this . validateFilePath ( filepath ) ; const absoluteFilePath = path . resolve ( process . cwd ( ) , filepath ) ; const runLoad = async ( ) : Promise < CosmiconfigResult > => { const fileContents = await readFile ( absoluteFilePath , { throwNotFound : true , } ) ; const result = await this . createCosmiconfigResult ( absoluteFilePath , fileContents ) ; const transformResult = await this . config . transform ( result ) ; return transformResult ; } ; if ( this . loadCache ) { return cacheWrapper ( this . loadCache , absoluteFilePath , runLoad ) ; } return runLoad ( ) ; } } export { Explorer } ;