Skip to content

Commit

Permalink
Implement async support for returning package a module was resolved f…
Browse files Browse the repository at this point in the history
…rom.
  • Loading branch information
jaredhanson authored and James Halliday committed Jun 9, 2013
1 parent 790cdf5 commit b7b2806
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 41 deletions.
50 changes: 30 additions & 20 deletions lib/async.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,40 +28,50 @@ module.exports = function resolve (x, opts, cb) {
opts.paths = opts.paths || [];

if (x.match(/^(?:\.\.?\/|\/|([A-Za-z]:)?\\)/)) {
loadAsFile(path.resolve(y, x), function (err, m) {
loadAsFile(path.resolve(y, x), function (err, m, pkg) {
if (err) cb(err)
else if (m) cb(null, m)
else loadAsDirectory(path.resolve(y, x), function (err, d) {
else if (m) cb(null, m, pkg)
else loadAsDirectory(path.resolve(y, x), function (err, d, pkg) {
if (err) cb(err)
else if (d) cb(null, d)
else if (d) cb(null, d, pkg)
else cb(new Error("Cannot find module '" + x + "'"))
})
});
}
else loadNodeModules(x, y, function (err, n) {
else loadNodeModules(x, y, function (err, n, pkg) {
if (err) cb(err)
else if (n) cb(null, n)
else if (n) cb(null, n, pkg)
else cb(new Error("Cannot find module '" + x + "'"))
});

function loadAsFile (x, cb) {
function loadAsFile (x, pkg, cb) {
if (typeof pkg === 'function') {
cb = pkg;
pkg = opts.package;
}

(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 if (ex) cb(null, file, pkg)
else load(exts.slice(1))
});
})([''].concat(extensions));
}

function loadAsDirectory (x, cb) {
function loadAsDirectory (x, fpkg, cb) {
if (typeof fpkg === 'function') {
cb = fpkg;
fpkg = opts.package;
}

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);
if (!ex) return loadAsFile(path.join(x, '/index'), fpkg, cb);

readFile(pkgfile, function (err, body) {
if (err) return cb(err);
Expand All @@ -75,20 +85,20 @@ module.exports = function resolve (x, opts, cb) {
}

if (pkg.main) {
loadAsFile(path.resolve(x, pkg.main), function (err, m) {
loadAsFile(path.resolve(x, pkg.main), pkg, function (err, m, pkg) {
if (err) return cb(err);
if (m) return cb(null, m);
if (m) return cb(null, m, pkg);
var dir = path.resolve(x, pkg.main);
loadAsDirectory(dir, function (err, n) {
loadAsDirectory(dir, pkg, function (err, n, pkg) {
if (err) return cb(err);
if (n) return cb(null, n);
loadAsFile(path.join(x, '/index'), cb);
if (n) return cb(null, n, pkg);
loadAsFile(path.join(x, '/index'), pkg, cb);
});
});
return;
}

loadAsFile(path.join(x, '/index'), cb);
loadAsFile(path.join(x, '/index'), pkg, cb);
});
});
}
Expand All @@ -98,12 +108,12 @@ module.exports = function resolve (x, opts, cb) {
if (dirs.length === 0) return cb(null, undefined);
var dir = dirs[0];

loadAsFile(path.join(dir, '/', x), function (err, m) {
loadAsFile(path.join(dir, '/', x), undefined, function (err, m, pkg) {
if (err) return cb(err);
if (m) return cb(null, m);
loadAsDirectory(path.join(dir, '/', x), function (err, n) {
if (m) return cb(null, m, pkg);
loadAsDirectory(path.join(dir, '/', x), undefined, function (err, n, pkg) {
if (err) return cb(err);
if (n) return cb(null, n);
if (n) return cb(null, n, pkg);
process(dirs.slice(1));
});
});
Expand Down
5 changes: 3 additions & 2 deletions test/filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@ var test = require('tap').test;
var resolve = require('../');

test('filter', function (t) {
t.plan(1);
t.plan(2);
var dir = __dirname + '/resolver';
resolve('./baz', {
basedir : dir,
packageFilter : function (pkg) {
pkg.main = 'doom';
return pkg;
}
}, function (err, res) {
}, function (err, res, pkg) {
if (err) t.fail(err);
t.equal(res, dir + '/baz/doom.js');
t.equal(pkg.main, 'doom');
});
});
84 changes: 79 additions & 5 deletions test/mock.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ var test = require('tap').test;
var resolve = require('../');

test('mock', function (t) {
t.plan(4);
t.plan(6);

var files = {
'/foo/bar/baz.js' : 'beep'
Expand All @@ -20,14 +20,57 @@ test('mock', function (t) {
}
}

resolve('./baz', opts('/foo/bar'), function (err, res) {
resolve('./baz', opts('/foo/bar'), function (err, res, pkg) {
if (err) t.fail(err);
t.equal(res, '/foo/bar/baz.js');
t.equal(pkg, undefined);
});

resolve('./baz.js', opts('/foo/bar'), function (err, res) {
resolve('./baz.js', opts('/foo/bar'), function (err, res, pkg) {
if (err) t.fail(err);
t.equal(res, '/foo/bar/baz.js');
t.equal(pkg, undefined);
});

resolve('baz', opts('/foo/bar'), function (err, res) {
t.equal(err.message, "Cannot find module 'baz'");
});

resolve('../baz', opts('/foo/bar'), function (err, res) {
t.equal(err.message, "Cannot find module '../baz'");
});
});

test('mock from package', function (t) {
t.plan(6);

var files = {
'/foo/bar/baz.js' : 'beep'
};

function opts (basedir) {
return {
basedir : basedir,
package : { main: 'bar' },
isFile : function (file, cb) {
cb(null, files.hasOwnProperty(file));
},
readFile : function (file, cb) {
cb(null, files[file]);
}
}
}

resolve('./baz', opts('/foo/bar'), function (err, res, pkg) {
if (err) t.fail(err);
t.equal(res, '/foo/bar/baz.js');
t.equal(pkg.main, 'bar');
});

resolve('./baz.js', opts('/foo/bar'), function (err, res, pkg) {
if (err) t.fail(err);
t.equal(res, '/foo/bar/baz.js');
t.equal(pkg.main, 'bar');
});

resolve('baz', opts('/foo/bar'), function (err, res) {
Expand All @@ -40,7 +83,36 @@ test('mock', function (t) {
});

test('mock package', function (t) {
t.plan(1);
t.plan(2);

var files = {
'/foo/node_modules/bar/baz.js' : 'beep',
'/foo/node_modules/bar/package.json' : JSON.stringify({
main : './baz.js'
})
};

function opts (basedir) {
return {
basedir : basedir,
isFile : function (file, cb) {
cb(null, files.hasOwnProperty(file));
},
readFile : function (file, cb) {
cb(null, files[file]);
}
}
}

resolve('bar', opts('/foo'), function (err, res, pkg) {
if (err) t.fail(err);
t.equal(res, '/foo/node_modules/bar/baz.js');
t.equal(pkg.main, './baz.js');
});
});

test('mock package from package', function (t) {
t.plan(2);

var files = {
'/foo/node_modules/bar/baz.js' : 'beep',
Expand All @@ -52,6 +124,7 @@ test('mock package', function (t) {
function opts (basedir) {
return {
basedir : basedir,
package : { main: 'bar' },
isFile : function (file, cb) {
cb(null, files.hasOwnProperty(file));
},
Expand All @@ -61,8 +134,9 @@ test('mock package', function (t) {
}
}

resolve('bar', opts('/foo'), function (err, res) {
resolve('bar', opts('/foo'), function (err, res, pkg) {
if (err) t.fail(err);
t.equal(res, '/foo/node_modules/bar/baz.js');
t.equal(pkg.main, './baz.js');
});
});
Loading

0 comments on commit b7b2806

Please sign in to comment.