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