--- /dev/null
+//
+'use strict';
+
+const path = require('path');
+const loadPackageProp = require('./loadPackageProp');
+const loadRc = require('./loadRc');
+const loadJs = require('./loadJs');
+const loadDefinedFile = require('./loadDefinedFile');
+const funcRunner = require('./funcRunner');
+const getDirectory = require('./getDirectory');
+
+module.exports = function createExplorer(options
+
+
+
+
+
+
+
+
+
+
+
+ ) {
+ // When `options.sync` is `false` (default),
+ // these cache Promises that resolve with results, not the results themselves.
+ const fileCache = options.cache ? new Map() : null;
+ const directoryCache = options.cache ? new Map() : null;
+ const transform = options.transform || identity;
+ const packageProp = options.packageProp;
+
+ function clearFileCache() {
+ if (fileCache) fileCache.clear();
+ }
+
+ function clearDirectoryCache() {
+ if (directoryCache) directoryCache.clear();
+ }
+
+ function clearCaches() {
+ clearFileCache();
+ clearDirectoryCache();
+ }
+
+ function throwError(error) {
+ if (options.sync) {
+ throw error;
+ } else {
+ return Promise.reject(error);
+ }
+ }
+
+ function load(
+ searchPath ,
+ configPath
+ ) {
+ if (!configPath && options.configPath) {
+ configPath = options.configPath;
+ }
+
+ if (configPath) {
+ const absoluteConfigPath = path.resolve(process.cwd(), configPath);
+ if (fileCache && fileCache.has(absoluteConfigPath)) {
+ return fileCache.get(absoluteConfigPath);
+ }
+
+ let load;
+ if (path.basename(absoluteConfigPath) === 'package.json') {
+ if (!packageProp) {
+ return throwError(
+ new Error(
+ 'Please specify the packageProp option. The configPath argument cannot point to a package.json file if packageProp is false.'
+ )
+ );
+ }
+ load = () =>
+ loadPackageProp(path.dirname(absoluteConfigPath), {
+ packageProp,
+ sync: options.sync,
+ });
+ } else {
+ load = () =>
+ loadDefinedFile(absoluteConfigPath, {
+ sync: options.sync,
+ format: options.format,
+ });
+ }
+
+ const loadResult = load();
+ const result =
+ loadResult instanceof Promise
+ ? loadResult.then(transform)
+ : transform(loadResult);
+ if (fileCache) fileCache.set(absoluteConfigPath, result);
+ return result;
+ }
+
+ if (!searchPath) return !options.sync ? Promise.resolve(null) : null;
+
+ const absoluteSearchPath = path.resolve(process.cwd(), searchPath);
+ const searchPathDir = getDirectory(absoluteSearchPath, options.sync);
+
+ return searchPathDir instanceof Promise
+ ? searchPathDir.then(searchDirectory)
+ : searchDirectory(searchPathDir);
+ }
+
+ function searchDirectory(
+ directory
+ ) {
+ if (directoryCache && directoryCache.has(directory)) {
+ return directoryCache.get(directory);
+ }
+
+ const result = funcRunner(!options.sync ? Promise.resolve() : undefined, [
+ () => {
+ if (!packageProp) return;
+ return loadPackageProp(directory, {
+ packageProp,
+ sync: options.sync,
+ });
+ },
+ result => {
+ if (result || !options.rc) return result;
+ return loadRc(path.join(directory, options.rc), {
+ sync: options.sync,
+ rcStrictJson: options.rcStrictJson,
+ rcExtensions: options.rcExtensions,
+ });
+ },
+ result => {
+ if (result || !options.js) return result;
+ return loadJs(path.join(directory, options.js), { sync: options.sync });
+ },
+ result => {
+ if (result) return result;
+
+ const nextDirectory = path.dirname(directory);
+
+ if (nextDirectory === directory || directory === options.stopDir)
+ return null;
+
+ return searchDirectory(nextDirectory);
+ },
+ transform,
+ ]);
+
+ if (directoryCache) directoryCache.set(directory, result);
+ return result;
+ }
+
+ return {
+ load,
+ clearFileCache,
+ clearDirectoryCache,
+ clearCaches,
+ };
+};
+
+function identity(x) {
+ return x;
+}