.gitignore added
[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 defaultReadPackage = function defaultReadPackage(readFile, pkgfile, cb) {
46     readFile(pkgfile, function (readFileErr, body) {
47         if (readFileErr) cb(readFileErr);
48         else {
49             try {
50                 var pkg = JSON.parse(body);
51                 cb(null, pkg);
52             } catch (jsonErr) {
53                 cb(null);
54             }
55         }
56     });
57 };
58
59 var getPackageCandidates = function getPackageCandidates(x, start, opts) {
60     var dirs = nodeModulesPaths(start, opts, x);
61     for (var i = 0; i < dirs.length; i++) {
62         dirs[i] = path.join(dirs[i], x);
63     }
64     return dirs;
65 };
66
67 module.exports = function resolve(x, options, callback) {
68     var cb = callback;
69     var opts = options;
70     if (typeof options === 'function') {
71         cb = opts;
72         opts = {};
73     }
74     if (typeof x !== 'string') {
75         var err = new TypeError('Path must be a string.');
76         return process.nextTick(function () {
77             cb(err);
78         });
79     }
80
81     opts = normalizeOptions(x, opts);
82
83     var isFile = opts.isFile || defaultIsFile;
84     var isDirectory = opts.isDirectory || defaultIsDir;
85     var readFile = opts.readFile || fs.readFile;
86     var realpath = opts.realpath || defaultRealpath;
87     var readPackage = opts.readPackage || defaultReadPackage;
88     if (opts.readFile && opts.readPackage) {
89         var conflictErr = new TypeError('`readFile` and `readPackage` are mutually exclusive.');
90         return process.nextTick(function () {
91             cb(conflictErr);
92         });
93     }
94     var packageIterator = opts.packageIterator;
95
96     var extensions = opts.extensions || ['.js'];
97     var includeCoreModules = opts.includeCoreModules !== false;
98     var basedir = opts.basedir || path.dirname(caller());
99     var parent = opts.filename || basedir;
100
101     opts.paths = opts.paths || [];
102
103     // ensure that `basedir` is an absolute path at this point, resolving against the process' current working directory
104     var absoluteStart = path.resolve(basedir);
105
106     maybeRealpath(
107         realpath,
108         absoluteStart,
109         opts,
110         function (err, realStart) {
111             if (err) cb(err);
112             else init(realStart);
113         }
114     );
115
116     var res;
117     function init(basedir) {
118         if ((/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/).test(x)) {
119             res = path.resolve(basedir, x);
120             if (x === '.' || x === '..' || x.slice(-1) === '/') res += '/';
121             if ((/\/$/).test(x) && res === basedir) {
122                 loadAsDirectory(res, opts.package, onfile);
123             } else loadAsFile(res, opts.package, onfile);
124         } else if (includeCoreModules && isCore(x)) {
125             return cb(null, x);
126         } else loadNodeModules(x, basedir, function (err, n, pkg) {
127             if (err) cb(err);
128             else if (n) {
129                 return maybeRealpath(realpath, n, opts, function (err, realN) {
130                     if (err) {
131                         cb(err);
132                     } else {
133                         cb(null, realN, 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 onfile(err, m, pkg) {
145         if (err) cb(err);
146         else if (m) cb(null, m, pkg);
147         else loadAsDirectory(res, function (err, d, pkg) {
148             if (err) cb(err);
149             else if (d) {
150                 maybeRealpath(realpath, d, opts, function (err, realD) {
151                     if (err) {
152                         cb(err);
153                     } else {
154                         cb(null, realD, pkg);
155                     }
156                 });
157             } else {
158                 var moduleError = new Error("Cannot find module '" + x + "' from '" + parent + "'");
159                 moduleError.code = 'MODULE_NOT_FOUND';
160                 cb(moduleError);
161             }
162         });
163     }
164
165     function loadAsFile(x, thePackage, callback) {
166         var loadAsFilePackage = thePackage;
167         var cb = callback;
168         if (typeof loadAsFilePackage === 'function') {
169             cb = loadAsFilePackage;
170             loadAsFilePackage = undefined;
171         }
172
173         var exts = [''].concat(extensions);
174         load(exts, x, loadAsFilePackage);
175
176         function load(exts, x, loadPackage) {
177             if (exts.length === 0) return cb(null, undefined, loadPackage);
178             var file = x + exts[0];
179
180             var pkg = loadPackage;
181             if (pkg) onpkg(null, pkg);
182             else loadpkg(path.dirname(file), onpkg);
183
184             function onpkg(err, pkg_, dir) {
185                 pkg = pkg_;
186                 if (err) return cb(err);
187                 if (dir && pkg && opts.pathFilter) {
188                     var rfile = path.relative(dir, file);
189                     var rel = rfile.slice(0, rfile.length - exts[0].length);
190                     var r = opts.pathFilter(pkg, x, rel);
191                     if (r) return load(
192                         [''].concat(extensions.slice()),
193                         path.resolve(dir, r),
194                         pkg
195                     );
196                 }
197                 isFile(file, onex);
198             }
199             function onex(err, ex) {
200                 if (err) return cb(err);
201                 if (ex) return cb(null, file, pkg);
202                 load(exts.slice(1), x, pkg);
203             }
204         }
205     }
206
207     function loadpkg(dir, cb) {
208         if (dir === '' || dir === '/') return cb(null);
209         if (process.platform === 'win32' && (/^\w:[/\\]*$/).test(dir)) {
210             return cb(null);
211         }
212         if ((/[/\\]node_modules[/\\]*$/).test(dir)) return cb(null);
213
214         maybeRealpath(realpath, dir, opts, function (unwrapErr, pkgdir) {
215             if (unwrapErr) return loadpkg(path.dirname(dir), cb);
216             var pkgfile = path.join(pkgdir, 'package.json');
217             isFile(pkgfile, function (err, ex) {
218                 // on err, ex is false
219                 if (!ex) return loadpkg(path.dirname(dir), cb);
220
221                 readPackage(readFile, pkgfile, function (err, pkgParam) {
222                     if (err) cb(err);
223
224                     var pkg = pkgParam;
225
226                     if (pkg && opts.packageFilter) {
227                         pkg = opts.packageFilter(pkg, pkgfile);
228                     }
229                     cb(null, pkg, dir);
230                 });
231             });
232         });
233     }
234
235     function loadAsDirectory(x, loadAsDirectoryPackage, callback) {
236         var cb = callback;
237         var fpkg = loadAsDirectoryPackage;
238         if (typeof fpkg === 'function') {
239             cb = fpkg;
240             fpkg = opts.package;
241         }
242
243         maybeRealpath(realpath, x, opts, function (unwrapErr, pkgdir) {
244             if (unwrapErr) return cb(unwrapErr);
245             var pkgfile = path.join(pkgdir, 'package.json');
246             isFile(pkgfile, function (err, ex) {
247                 if (err) return cb(err);
248                 if (!ex) return loadAsFile(path.join(x, 'index'), fpkg, cb);
249
250                 readPackage(readFile, pkgfile, function (err, pkgParam) {
251                     if (err) return cb(err);
252
253                     var pkg = pkgParam;
254
255                     if (pkg && opts.packageFilter) {
256                         pkg = opts.packageFilter(pkg, pkgfile);
257                     }
258
259                     if (pkg && pkg.main) {
260                         if (typeof pkg.main !== 'string') {
261                             var mainError = new TypeError('package “' + pkg.name + '” `main` must be a string');
262                             mainError.code = 'INVALID_PACKAGE_MAIN';
263                             return cb(mainError);
264                         }
265                         if (pkg.main === '.' || pkg.main === './') {
266                             pkg.main = 'index';
267                         }
268                         loadAsFile(path.resolve(x, pkg.main), pkg, function (err, m, pkg) {
269                             if (err) return cb(err);
270                             if (m) return cb(null, m, pkg);
271                             if (!pkg) return loadAsFile(path.join(x, 'index'), pkg, cb);
272
273                             var dir = path.resolve(x, pkg.main);
274                             loadAsDirectory(dir, pkg, function (err, n, pkg) {
275                                 if (err) return cb(err);
276                                 if (n) return cb(null, n, pkg);
277                                 loadAsFile(path.join(x, 'index'), pkg, cb);
278                             });
279                         });
280                         return;
281                     }
282
283                     loadAsFile(path.join(x, '/index'), pkg, cb);
284                 });
285             });
286         });
287     }
288
289     function processDirs(cb, dirs) {
290         if (dirs.length === 0) return cb(null, undefined);
291         var dir = dirs[0];
292
293         isDirectory(path.dirname(dir), isdir);
294
295         function isdir(err, isdir) {
296             if (err) return cb(err);
297             if (!isdir) return processDirs(cb, dirs.slice(1));
298             loadAsFile(dir, opts.package, onfile);
299         }
300
301         function onfile(err, m, pkg) {
302             if (err) return cb(err);
303             if (m) return cb(null, m, pkg);
304             loadAsDirectory(dir, opts.package, ondir);
305         }
306
307         function ondir(err, n, pkg) {
308             if (err) return cb(err);
309             if (n) return cb(null, n, pkg);
310             processDirs(cb, dirs.slice(1));
311         }
312     }
313     function loadNodeModules(x, start, cb) {
314         var thunk = function () { return getPackageCandidates(x, start, opts); };
315         processDirs(
316             cb,
317             packageIterator ? packageIterator(x, start, thunk, opts) : thunk()
318         );
319     }
320 };