Initial commit
[yaffs-website] / node_modules / cosmiconfig / lib / createExplorer.js
1 'use strict';
2
3 var path = require('path');
4 var fs = require('fs');
5 var loadPackageProp = require('./loadPackageProp');
6 var loadRc = require('./loadRc');
7 var loadJs = require('./loadJs');
8 var loadDefinedFile = require('./loadDefinedFile');
9
10 module.exports = function (options) {
11   // These cache Promises that resolve with results, not the results themselves
12   var fileCache = (options.cache) ? new Map() : null;
13   var directoryCache = (options.cache) ? new Map() : null;
14   var transform = options.transform || identityPromise;
15
16   function clearFileCache() {
17     if (fileCache) fileCache.clear();
18   }
19
20   function clearDirectoryCache() {
21     if (directoryCache) directoryCache.clear();
22   }
23
24   function clearCaches() {
25     clearFileCache();
26     clearDirectoryCache();
27   }
28
29   function load(searchPath, configPath) {
30     if (configPath) {
31       var absoluteConfigPath = path.resolve(process.cwd(), configPath);
32       if (fileCache && fileCache.has(absoluteConfigPath)) {
33         return fileCache.get(absoluteConfigPath);
34       }
35       var result = loadDefinedFile(absoluteConfigPath, options)
36         .then(transform);
37       if (fileCache) fileCache.set(absoluteConfigPath, result);
38       return result;
39     }
40
41     if (!searchPath) return Promise.resolve(null);
42
43     var absoluteSearchPath = path.resolve(process.cwd(), searchPath);
44
45     return isDirectory(absoluteSearchPath)
46       .then(function (searchPathIsDirectory) {
47         var directory = (searchPathIsDirectory)
48           ? absoluteSearchPath
49           : path.dirname(absoluteSearchPath);
50         return searchDirectory(directory);
51       });
52   }
53
54   function searchDirectory(directory) {
55     if (directoryCache && directoryCache.has(directory)) {
56       return directoryCache.get(directory);
57     }
58
59     var result = Promise.resolve()
60       .then(function () {
61         if (!options.packageProp) return;
62         return loadPackageProp(directory, options);
63       })
64       .then(function (result) {
65         if (result || !options.rc) return result;
66         return loadRc(path.join(directory, options.rc), options);
67       })
68       .then(function (result) {
69         if (result || !options.js) return result;
70         return loadJs(path.join(directory, options.js));
71       })
72       .then(function (result) {
73         if (result) return result;
74
75         var splitPath = directory.split(path.sep);
76         var nextDirectory = (splitPath.length > 1)
77           ? splitPath.slice(0, -1).join(path.sep)
78           : null;
79
80         if (!nextDirectory || directory === options.stopDir) return null;
81
82         return searchDirectory(nextDirectory);
83       })
84       .then(transform);
85
86     if (directoryCache) directoryCache.set(directory, result);
87     return result;
88   }
89
90   return {
91     load: load,
92     clearFileCache: clearFileCache,
93     clearDirectoryCache: clearDirectoryCache,
94     clearCaches: clearCaches,
95   };
96 };
97
98 function isDirectory(filepath) {
99   return new Promise(function (resolve, reject) {
100     fs.stat(filepath, function (err, stats) {
101       if (err) return reject(err);
102       return resolve(stats.isDirectory());
103     });
104   });
105 }
106
107 function identityPromise(x) {
108   return Promise.resolve(x);
109 }