source: imaps-frontend/node_modules/resolve/lib/async.js

main
Last change on this file was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

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