closest-file-data
Version:
Allow to find and retrieve some data (such as config file) related to a given path (with cache)
49 lines (48 loc) • 1.82 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = require("fs");
const path_1 = require("path");
let caches = Object.create(null);
function closestFileData(relPath, oneOrMoreReader) {
const paths = [];
const readers = Array.isArray(oneOrMoreReader) ? oneOrMoreReader : [oneOrMoreReader];
if (readers.length < 1) {
throw new RangeError(`At least one reader must be given.`);
}
// cache key is based on the ordered list of basenames
const cacheKey = readers.map(r => r.basename).join('::');
if (!(cacheKey in caches)) {
caches[cacheKey] = Object.create(null);
}
const cache = caches[cacheKey];
let result;
let directory = relPath;
do {
if (directory in cache) {
result = cache[directory];
break;
}
paths.push(directory);
// look for a config using readers (config file must exists and reader must not return null)
readers.find(({ basename, read }) => {
const path = path_1.join(directory, basename);
if (fs_1.existsSync(path)) {
const config = read(path);
if (typeof config !== 'undefined') {
result = Object.freeze({ path, data: config });
return true;
}
}
return false;
});
// continue while we don't have a config and there is a parent directory
} while (!result && directory !== (directory = path_1.dirname(directory))); // tslint:disable-line
// each directory will resolve to the same config
paths.forEach(d => (cache[d] = result));
return result;
}
exports.default = Object.assign(closestFileData, {
cache: {
clear: () => (caches = Object.create(null)),
},
});
;