4 const path = require('path');
5 const loadPackageProp = require('./loadPackageProp');
6 const loadRc = require('./loadRc');
7 const loadJs = require('./loadJs');
8 const loadDefinedFile = require('./loadDefinedFile');
9 const funcRunner = require('./funcRunner');
10 const getDirectory = require('./getDirectory');
12 module.exports = function createExplorer(options
25 // When `options.sync` is `false` (default),
26 // these cache Promises that resolve with results, not the results themselves.
27 const fileCache = options.cache ? new Map() : null;
28 const directoryCache = options.cache ? new Map() : null;
29 const transform = options.transform || identity;
30 const packageProp = options.packageProp;
32 function clearFileCache() {
33 if (fileCache) fileCache.clear();
36 function clearDirectoryCache() {
37 if (directoryCache) directoryCache.clear();
40 function clearCaches() {
42 clearDirectoryCache();
45 function throwError(error) {
49 return Promise.reject(error);
57 if (!configPath && options.configPath) {
58 configPath = options.configPath;
62 const absoluteConfigPath = path.resolve(process.cwd(), configPath);
63 if (fileCache && fileCache.has(absoluteConfigPath)) {
64 return fileCache.get(absoluteConfigPath);
68 if (path.basename(absoluteConfigPath) === 'package.json') {
72 'Please specify the packageProp option. The configPath argument cannot point to a package.json file if packageProp is false.'
77 loadPackageProp(path.dirname(absoluteConfigPath), {
83 loadDefinedFile(absoluteConfigPath, {
85 format: options.format,
89 const loadResult = load();
91 loadResult instanceof Promise
92 ? loadResult.then(transform)
93 : transform(loadResult);
94 if (fileCache) fileCache.set(absoluteConfigPath, result);
98 if (!searchPath) return !options.sync ? Promise.resolve(null) : null;
100 const absoluteSearchPath = path.resolve(process.cwd(), searchPath);
101 const searchPathDir = getDirectory(absoluteSearchPath, options.sync);
103 return searchPathDir instanceof Promise
104 ? searchPathDir.then(searchDirectory)
105 : searchDirectory(searchPathDir);
108 function searchDirectory(
111 if (directoryCache && directoryCache.has(directory)) {
112 return directoryCache.get(directory);
115 const result = funcRunner(!options.sync ? Promise.resolve() : undefined, [
117 if (!packageProp) return;
118 return loadPackageProp(directory, {
124 if (result || !options.rc) return result;
125 return loadRc(path.join(directory, options.rc), {
127 rcStrictJson: options.rcStrictJson,
128 rcExtensions: options.rcExtensions,
132 if (result || !options.js) return result;
133 return loadJs(path.join(directory, options.js), { sync: options.sync });
136 if (result) return result;
138 const nextDirectory = path.dirname(directory);
140 if (nextDirectory === directory || directory === options.stopDir)
143 return searchDirectory(nextDirectory);
148 if (directoryCache) directoryCache.set(directory, result);
160 function identity(x) {