Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / resolve / lib / async.js
1 var fs = require('fs');
2 var path = require('path');
3 var caller = require('./caller');
4 var nodeModulesPaths = require('./node-modules-paths');
5 var normalizeOptions = require('./normalize-options');
6 var isCore = require('is-core-module');
7
8 var realpathFS = fs.realpath && typeof fs.realpath.native === 'function' ? fs.realpath.native : fs.realpath;
9
10 var defaultIsFile = function isFile(file, cb) {
11     fs.stat(file, function (err, stat) {
12         if (!err) {
13             return cb(null, stat.isFile() || stat.isFIFO());
14         }
15         if (err.code === 'ENOENT' || err.code === 'ENOTDIR') return cb(null, false);
16         return cb(err);
17     });
18 };
19
20 var defaultIsDir = function isDirectory(dir, cb) {
21     fs.stat(dir, function (err, stat) {
22         if (!err) {
23             return cb(null, stat.isDirectory());
24         }
25         if (err.code === 'ENOENT' || err.code === 'ENOTDIR') return cb(null, false);
26         return cb(err);
27     });
28 };
29
30 var defaultRealpath = function realpath(x, cb) {
31     realpathFS(x, function (realpathErr, realPath) {
32         if (realpathErr && realpathErr.code !== 'ENOENT') cb(realpathErr);
33         else cb(null, realpathErr ? x : realPath);
34     });
35 };
36
37 var maybeRealpath = function maybeRealpath(realpath, x, opts, cb) {
38     if (opts && opts.preserveSymlinks === false) {
39         realpath(x, cb);
40     } else {
41         cb(null, x);
42     }
43 };
44
45 var getPackageCandidates = function getPackageCandidates(x, start, opts) {
46     var dirs = nodeModulesPaths(start, opts, x);
47     for (var i = 0; i < dirs.length; i++) {
48         dirs[i] = path.join(dirs[i], x);
49     }
50     return dirs;
51 };
52
53 module.exports = function resolve(x, options, callback) {
54     var cb = callback;
55     var opts = options;
56     if (typeof options === 'function') {
57         cb = opts;
58         opts = {};
59     }
60     if (typeof x !== 'string') {
61         var err = new TypeError('Path must be a string.');
62         return process.nextTick(function () {
63             cb(err);
64         });
65     }
66
67     opts = normalizeOptions(x, opts);
68
69     var isFile = opts.isFile || defaultIsFile;
70     var isDirectory = opts.isDirectory || defaultIsDir;
71     var readFile = opts.readFile || fs.readFile;
72     var realpath = opts.realpath || defaultRealpath;
73     var packageIterator = opts.packageIterator;
74
75     var extensions = opts.extensions || ['.js'];
76     var includeCoreModules = opts.includeCoreModules !== false;
77     var basedir = opts.basedir || path.dirname(caller());
78     var parent = opts.filename || basedir;
79
80     opts.paths = opts.paths || [];
81
82     // ensure that `basedir` is an absolute path at this point, resolving against the process' current working directory
83     var absoluteStart = path.resolve(basedir);
84
85     maybeRealpath(
86         realpath,
87         absoluteStart,
88         opts,
89         function (err, realStart) {
90             if (err) cb(err);
91             else init(realStart);
92         }
93     );
94
95     var res;
96     function init(basedir) {
97         if ((/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/).test(x)) {
98             res = path.resolve(basedir, x);
99             if (x === '.' || x === '..' || x.slice(-1) === '/') res += '/';
100             if ((/\/$/).test(x) && res === basedir) {
101                 loadAsDirectory(res, opts.package, onfile);
102             } else loadAsFile(res, opts.package, onfile);
103         } else if (includeCoreModules && isCore(x)) {
104             return cb(null, x);
105         } else loadNodeModules(x, basedir, function (err, n, pkg) {
106             if (err) cb(err);
107             else if (n) {
108                 return maybeRealpath(realpath, n, opts, function (err, realN) {
109                     if (err) {
110                         cb(err);
111                     } else {
112                         cb(null, realN, pkg);
113                     }
114                 });
115             } else {
116                 var moduleError = new Error("Cannot find module '" + x + "' from '" + parent + "'");
117                 moduleError.code = 'MODULE_NOT_FOUND';
118                 cb(moduleError);
119             }
120         });
121     }
122
123     function onfile(err, m, pkg) {
124         if (err) cb(err);
125         else if (m) cb(null, m, pkg);
126         else loadAsDirectory(res, function (err, d, pkg) {
127             if (err) cb(err);
128             else if (d) {
129                 maybeRealpath(realpath, d, opts, function (err, realD) {
130                     if (err) {
131                         cb(err);
132                     } else {
133                         cb(null, realD, pkg);
134                     }
135                 });
136             } else {
137                 var moduleError = new Error("Cannot find module '" + x + "' from '" + parent + "'");
138                 moduleError.code = 'MODULE_NOT_FOUND';
139                 cb(moduleError);
140             }
141         });
142     }
143
144     function loadAsFile(x, thePackage, callback) {
145         var loadAsFilePackage = thePackage;
146         var cb = callback;
147         if (typeof loadAsFilePackage === 'function') {
148             cb = loadAsFilePackage;
149             loadAsFilePackage = undefined;
150         }
151
152         var exts = [''].concat(extensions);
153         load(exts, x, loadAsFilePackage);
154
155         function load(exts, x, loadPackage) {
156             if (exts.length === 0) return cb(null, undefined, loadPackage);
157             var file = x + exts[0];
158
159             var pkg = loadPackage;
160             if (pkg) onpkg(null, pkg);
161             else loadpkg(path.dirname(file), onpkg);
162
163             function onpkg(err, pkg_, dir) {
164                 pkg = pkg_;
165                 if (err) return cb(err);
166                 if (dir && pkg && opts.pathFilter) {
167                     var rfile = path.relative(dir, file);
168                     var rel = rfile.slice(0, rfile.length - exts[0].length);
169                     var r = opts.pathFilter(pkg, x, rel);
170                     if (r) return load(
171                         [''].concat(extensions.slice()),
172                         path.resolve(dir, r),
173                         pkg
174                     );
175                 }
176                 isFile(file, onex);
177             }
178             function onex(err, ex) {
179                 if (err) return cb(err);
180                 if (ex) return cb(null, file, pkg);
181                 load(exts.slice(1), x, pkg);
182             }
183         }
184     }
185
186     function loadpkg(dir, cb) {
187         if (dir === '' || dir === '/') return cb(null);
188         if (process.platform === 'win32' && (/^\w:[/\\]*$/).test(dir)) {
189             return cb(null);
190         }
191         if ((/[/\\]node_modules[/\\]*$/).test(dir)) return cb(null);
192
193         maybeRealpath(realpath, dir, opts, function (unwrapErr, pkgdir) {
194             if (unwrapErr) return loadpkg(path.dirname(dir), cb);
195             var pkgfile = path.join(pkgdir, 'package.json');
196             isFile(pkgfile, function (err, ex) {
197                 // on err, ex is false
198                 if (!ex) return loadpkg(path.dirname(dir), cb);
199
200                 readFile(pkgfile, function (err, body) {
201                     if (err) cb(err);
202                     try { var pkg = JSON.parse(body); } catch (jsonErr) {}
203
204                     if (pkg && opts.packageFilter) {
205                         pkg = opts.packageFilter(pkg, pkgfile);
206                     }
207                     cb(null, pkg, dir);
208                 });
209             });
210         });
211     }
212
213     function loadAsDirectory(x, loadAsDirectoryPackage, callback) {
214         var cb = callback;
215         var fpkg = loadAsDirectoryPackage;
216         if (typeof fpkg === 'function') {
217             cb = fpkg;
218             fpkg = opts.package;
219         }
220
221         maybeRealpath(realpath, x, opts, function (unwrapErr, pkgdir) {
222             if (unwrapErr) return cb(unwrapErr);
223             var pkgfile = path.join(pkgdir, 'package.json');
224             isFile(pkgfile, function (err, ex) {
225                 if (err) return cb(err);
226                 if (!ex) return loadAsFile(path.join(x, 'index'), fpkg, cb);
227
228                 readFile(pkgfile, function (err, body) {
229                     if (err) return cb(err);
230                     try {
231                         var pkg = JSON.parse(body);
232                     } catch (jsonErr) {}
233
234                     if (pkg && opts.packageFilter) {
235                         pkg = opts.packageFilter(pkg, pkgfile);
236                     }
237
238                     if (pkg && pkg.main) {
239                         if (typeof pkg.main !== 'string') {
240                             var mainError = new TypeError('package “' + pkg.name + '” `main` must be a string');
241                             mainError.code = 'INVALID_PACKAGE_MAIN';
242                             return cb(mainError);
243                         }
244                         if (pkg.main === '.' || pkg.main === './') {
245                             pkg.main = 'index';
246                         }
247                         loadAsFile(path.resolve(x, pkg.main), pkg, function (err, m, pkg) {
248                             if (err) return cb(err);
249                             if (m) return cb(null, m, pkg);
250                             if (!pkg) return loadAsFile(path.join(x, 'index'), pkg, cb);
251
252                             var dir = path.resolve(x, pkg.main);
253                             loadAsDirectory(dir, pkg, function (err, n, pkg) {
254                                 if (err) return cb(err);
255                                 if (n) return cb(null, n, pkg);
256                                 loadAsFile(path.join(x, 'index'), pkg, cb);
257                             });
258                         });
259                         return;
260                     }
261
262                     loadAsFile(path.join(x, '/index'), pkg, cb);
263                 });
264             });
265         });
266     }
267
268     function processDirs(cb, dirs) {
269         if (dirs.length === 0) return cb(null, undefined);
270         var dir = dirs[0];
271
272         isDirectory(path.dirname(dir), isdir);
273
274         function isdir(err, isdir) {
275             if (err) return cb(err);
276             if (!isdir) return processDirs(cb, dirs.slice(1));
277             loadAsFile(dir, opts.package, onfile);
278         }
279
280         function onfile(err, m, pkg) {
281             if (err) return cb(err);
282             if (m) return cb(null, m, pkg);
283             loadAsDirectory(dir, opts.package, ondir);
284         }
285
286         function ondir(err, n, pkg) {
287             if (err) return cb(err);
288             if (n) return cb(null, n, pkg);
289             processDirs(cb, dirs.slice(1));
290         }
291     }
292     function loadNodeModules(x, start, cb) {
293         var thunk = function () { return getPackageCandidates(x, start, opts); };
294         processDirs(
295             cb,
296             packageIterator ? packageIterator(x, start, thunk, opts) : thunk()
297         );
298     }
299 };