90 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			90 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | 'use strict'; | ||
|  | const path = require('path'); | ||
|  | const locatePath = require('locate-path'); | ||
|  | const pathExists = require('path-exists'); | ||
|  | 
 | ||
|  | const stop = Symbol('findUp.stop'); | ||
|  | 
 | ||
|  | module.exports = async (name, options = {}) => { | ||
|  | 	let directory = path.resolve(options.cwd || ''); | ||
|  | 	const {root} = path.parse(directory); | ||
|  | 	const paths = [].concat(name); | ||
|  | 
 | ||
|  | 	const runMatcher = async locateOptions => { | ||
|  | 		if (typeof name !== 'function') { | ||
|  | 			return locatePath(paths, locateOptions); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		const foundPath = await name(locateOptions.cwd); | ||
|  | 		if (typeof foundPath === 'string') { | ||
|  | 			return locatePath([foundPath], locateOptions); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		return foundPath; | ||
|  | 	}; | ||
|  | 
 | ||
|  | 	// eslint-disable-next-line no-constant-condition
 | ||
|  | 	while (true) { | ||
|  | 		// eslint-disable-next-line no-await-in-loop
 | ||
|  | 		const foundPath = await runMatcher({...options, cwd: directory}); | ||
|  | 
 | ||
|  | 		if (foundPath === stop) { | ||
|  | 			return; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		if (foundPath) { | ||
|  | 			return path.resolve(directory, foundPath); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		if (directory === root) { | ||
|  | 			return; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		directory = path.dirname(directory); | ||
|  | 	} | ||
|  | }; | ||
|  | 
 | ||
|  | module.exports.sync = (name, options = {}) => { | ||
|  | 	let directory = path.resolve(options.cwd || ''); | ||
|  | 	const {root} = path.parse(directory); | ||
|  | 	const paths = [].concat(name); | ||
|  | 
 | ||
|  | 	const runMatcher = locateOptions => { | ||
|  | 		if (typeof name !== 'function') { | ||
|  | 			return locatePath.sync(paths, locateOptions); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		const foundPath = name(locateOptions.cwd); | ||
|  | 		if (typeof foundPath === 'string') { | ||
|  | 			return locatePath.sync([foundPath], locateOptions); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		return foundPath; | ||
|  | 	}; | ||
|  | 
 | ||
|  | 	// eslint-disable-next-line no-constant-condition
 | ||
|  | 	while (true) { | ||
|  | 		const foundPath = runMatcher({...options, cwd: directory}); | ||
|  | 
 | ||
|  | 		if (foundPath === stop) { | ||
|  | 			return; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		if (foundPath) { | ||
|  | 			return path.resolve(directory, foundPath); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		if (directory === root) { | ||
|  | 			return; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		directory = path.dirname(directory); | ||
|  | 	} | ||
|  | }; | ||
|  | 
 | ||
|  | module.exports.exists = pathExists; | ||
|  | 
 | ||
|  | module.exports.sync.exists = pathExists.sync; | ||
|  | 
 | ||
|  | module.exports.stop = stop; |