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;
 |