Simon Priet 9e2991e668 init
2021-09-05 22:53:58 +02:00

160 lines
4.3 KiB
JavaScript

//
'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 (!searchPath) searchPath = process.cwd();
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;
}
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;
}