-
-
Notifications
You must be signed in to change notification settings - Fork 183
/
async.js
131 lines (114 loc) · 4.31 KB
/
async.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
var core = require('./core');
var fs = require('fs');
var path = require('path');
module.exports = function resolve (x, opts, cb) {
if (core[x]) return cb(null, x);
if (typeof opts === 'function') {
cb = opts;
opts = {};
}
if (!opts) opts = {};
var isFile = opts.isFile || function (file, cb) {
fs.stat(file, function (err, stat) {
if (err && err.code === 'ENOENT') cb(null, false)
else if (err) cb(err)
else cb(null, !stat.isDirectory())
});
};
var readFile = opts.readFile || fs.readFile;
var extensions = opts.extensions || [ '.js' ];
var y = opts.basedir
|| path.dirname(require.cache[__filename].parent.filename)
;
opts.paths = opts.paths || [];
if (x.match(/^(?:\.\.?\/|\/|([A-Za-z]:)?\\)/)) {
loadAsFile(path.resolve(y, x), function (err, m) {
if (err) cb(err)
else if (m) cb(null, m)
else loadAsDirectory(path.resolve(y, x), function (err, d) {
if (err) cb(err)
else if (d) cb(null, d)
else cb(new Error("Cannot find module '" + x + "'"))
})
});
}
else loadNodeModules(x, y, function (err, n) {
if (err) cb(err)
else if (n) cb(null, n)
else cb(new Error("Cannot find module '" + x + "'"))
});
function loadAsFile (x, cb) {
(function load (exts) {
if (exts.length === 0) return cb(null, undefined);
var file = x + exts[0];
isFile(file, function (err, ex) {
if (err) cb(err)
else if (ex) cb(null, file)
else load(exts.slice(1))
});
})([''].concat(extensions));
}
function loadAsDirectory (x, cb) {
var pkgfile = path.join(x, '/package.json');
isFile(pkgfile, function (err, ex) {
if (err) return cb(err);
if (!ex) return loadAsFile(path.join(x, '/index'), cb);
readFile(pkgfile, function (err, body) {
if (err) return cb(err);
try {
var pkg = JSON.parse(body);
}
catch (err) {}
if (opts.packageFilter) {
pkg = opts.packageFilter(pkg, x);
}
if (pkg.main) {
loadAsFile(path.resolve(x, pkg.main), function (err, m) {
if (err) return cb(err);
if (m) return cb(null, m);
var dir = path.resolve(x, pkg.main);
loadAsDirectory(dir, function (err, n) {
if (err) return cb(err);
if (n) return cb(null, n);
loadAsFile(path.join(x, '/index'), cb);
});
});
return;
}
loadAsFile(path.join(x, '/index'), cb);
});
});
}
function loadNodeModules (x, start, cb) {
(function process (dirs) {
if (dirs.length === 0) return cb(null, undefined);
var dir = dirs[0];
loadAsFile(path.join(dir, '/', x), function (err, m) {
if (err) return cb(err);
if (m) return cb(null, m);
loadAsDirectory(path.join(dir, '/', x), function (err, n) {
if (err) return cb(err);
if (n) return cb(null, n);
process(dirs.slice(1));
});
});
})(nodeModulesPaths(start));
}
function nodeModulesPaths (start, cb) {
var splitRe = process.platform === 'win32' ? /[\/\\]/ : /\/+/;
var parts = start.split(splitRe);
var dirs = [];
for (var i = parts.length - 1; i >= 0; i--) {
if (parts[i] === 'node_modules') continue;
var dir = path.join(
path.join.apply(path, parts.slice(0, i + 1)),
'node_modules'
);
if (!parts[0].match(/([A-Za-z]:)/)) {
dir = '/' + dir;
}
dirs.push(dir);
}
return dirs.concat(opts.paths);
}
};