Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80529 views
1
var core = require('./core');
2
var fs = require('fs');
3
var path = require('path');
4
var caller = require('./caller.js');
5
var nodeModulesPaths = require('./node-modules-paths.js');
6
var splitRe = process.platform === 'win32' ? /[\/\\]/ : /\//;
7
8
module.exports = function resolve (x, opts, cb) {
9
if (typeof opts === 'function') {
10
cb = opts;
11
opts = {};
12
}
13
if (!opts) opts = {};
14
if (typeof x !== 'string') {
15
return process.nextTick(function () {
16
cb(new Error('path must be a string'));
17
});
18
}
19
20
var isFile = opts.isFile || function (file, cb) {
21
fs.stat(file, function (err, stat) {
22
if (err && err.code === 'ENOENT') cb(null, false)
23
else if (err) cb(err)
24
else cb(null, stat.isFile() || stat.isFIFO())
25
});
26
};
27
var readFile = opts.readFile || fs.readFile;
28
29
var extensions = opts.extensions || [ '.js' ];
30
var y = opts.basedir || path.dirname(caller());
31
32
opts.paths = opts.paths || [];
33
34
if (/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[\\\/])/.test(x)) {
35
var res = path.resolve(y, x);
36
if (x === '..') res += '/';
37
if (/\/$/.test(x) && res === y) {
38
loadAsDirectory(res, opts.package, onfile);
39
}
40
else loadAsFile(res, opts.package, onfile);
41
}
42
else loadNodeModules(x, y, function (err, n, pkg) {
43
if (err) cb(err)
44
else if (n) cb(null, n, pkg)
45
else if (core[x]) return cb(null, x);
46
else cb(new Error("Cannot find module '" + x + "' from '" + y + "'"))
47
});
48
49
function onfile (err, m, pkg) {
50
if (err) cb(err)
51
else if (m) cb(null, m, pkg)
52
else loadAsDirectory(res, function (err, d, pkg) {
53
if (err) cb(err)
54
else if (d) cb(null, d, pkg)
55
else cb(new Error("Cannot find module '" + x + "' from '" + y + "'"))
56
})
57
}
58
59
function loadAsFile (x, pkg, cb) {
60
if (typeof pkg === 'function') {
61
cb = pkg;
62
pkg = undefined;
63
}
64
65
var exts = [''].concat(extensions);
66
load(exts, x, pkg)
67
68
function load (exts, x, pkg) {
69
if (exts.length === 0) return cb(null, undefined, pkg);
70
var file = x + exts[0];
71
72
if (pkg) onpkg(null, pkg)
73
else loadpkg(path.dirname(file), onpkg);
74
75
function onpkg (err, pkg_, dir) {
76
pkg = pkg_;
77
if (err) return cb(err)
78
if (dir && pkg && opts.pathFilter) {
79
var rfile = path.relative(dir, file);
80
var rel = rfile.slice(0, rfile.length - exts[0].length);
81
var r = opts.pathFilter(pkg, x, rel);
82
if (r) return load(
83
[''].concat(extensions.slice()),
84
path.resolve(dir, r),
85
pkg
86
);
87
}
88
isFile(file, onex);
89
}
90
function onex (err, ex) {
91
if (err) cb(err)
92
else if (!ex) load(exts.slice(1), x, pkg)
93
else cb(null, file, pkg)
94
}
95
}
96
}
97
98
function loadpkg (dir, cb) {
99
if (dir === '' || dir === '/') return cb(null);
100
if (process.platform === 'win32' && /^\w:[\\\/]*$/.test(dir)) {
101
return cb(null);
102
}
103
if (/[\\\/]node_modules[\\\/]*$/.test(dir)) return cb(null);
104
105
var pkgfile = path.join(dir, 'package.json');
106
isFile(pkgfile, function (err, ex) {
107
// on err, ex is false
108
if (!ex) return loadpkg(
109
path.dirname(dir), cb
110
);
111
112
readFile(pkgfile, function (err, body) {
113
if (err) cb(err);
114
try { var pkg = JSON.parse(body) }
115
catch (err) {}
116
117
if (pkg && opts.packageFilter) {
118
pkg = opts.packageFilter(pkg, pkgfile);
119
}
120
cb(null, pkg, dir);
121
});
122
});
123
}
124
125
function loadAsDirectory (x, fpkg, cb) {
126
if (typeof fpkg === 'function') {
127
cb = fpkg;
128
fpkg = opts.package;
129
}
130
131
var pkgfile = path.join(x, '/package.json');
132
isFile(pkgfile, function (err, ex) {
133
if (err) return cb(err);
134
if (!ex) return loadAsFile(path.join(x, '/index'), fpkg, cb);
135
136
readFile(pkgfile, function (err, body) {
137
if (err) return cb(err);
138
try {
139
var pkg = JSON.parse(body);
140
}
141
catch (err) {}
142
143
if (opts.packageFilter) {
144
pkg = opts.packageFilter(pkg, pkgfile);
145
}
146
147
if (pkg.main) {
148
if (pkg.main === '.' || pkg.main === './'){
149
pkg.main = 'index'
150
}
151
loadAsFile(path.resolve(x, pkg.main), pkg, function (err, m, pkg) {
152
if (err) return cb(err);
153
if (m) return cb(null, m, pkg);
154
if (!pkg) return loadAsFile(path.join(x, '/index'), pkg, cb);
155
156
var dir = path.resolve(x, pkg.main);
157
loadAsDirectory(dir, pkg, function (err, n, pkg) {
158
if (err) return cb(err);
159
if (n) return cb(null, n, pkg);
160
loadAsFile(path.join(x, '/index'), pkg, cb);
161
});
162
});
163
return;
164
}
165
166
loadAsFile(path.join(x, '/index'), pkg, cb);
167
});
168
});
169
}
170
171
function loadNodeModules (x, start, cb) {
172
(function process (dirs) {
173
if (dirs.length === 0) return cb(null, undefined);
174
var dir = dirs[0];
175
176
var file = path.join(dir, '/', x);
177
loadAsFile(file, undefined, onfile);
178
179
function onfile (err, m, pkg) {
180
if (err) return cb(err);
181
if (m) return cb(null, m, pkg);
182
loadAsDirectory(path.join(dir, '/', x), undefined, ondir);
183
}
184
185
function ondir (err, n, pkg) {
186
if (err) return cb(err);
187
if (n) return cb(null, n, pkg);
188
process(dirs.slice(1));
189
}
190
})(nodeModulesPaths(start, opts));
191
}
192
};
193
194