Skip to content

Commit

Permalink
feat: add readPkg and readPkgSync
Browse files Browse the repository at this point in the history
  • Loading branch information
SimenB committed Jan 30, 2021
1 parent 4bece07 commit 98b6d92
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 15 deletions.
27 changes: 21 additions & 6 deletions lib/async.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ var maybeRealpath = function maybeRealpath(realpath, x, opts, cb) {
}
};

var defaultReadPkg = function defaultReadPkg(readFile, pkgfile, cb) {
readFile(pkgfile, function (readFileErr, body) {
if (readFileErr) cb(readFileErr);
else {
try {
var pkg = JSON.parse(body);
cb(null, pkg);
} catch (jsonErr) {
cb(null);
}
}
});
};

var getPackageCandidates = function getPackageCandidates(x, start, opts) {
var dirs = nodeModulesPaths(start, opts, x);
for (var i = 0; i < dirs.length; i++) {
Expand Down Expand Up @@ -70,6 +84,7 @@ module.exports = function resolve(x, options, callback) {
var isDirectory = opts.isDirectory || defaultIsDir;
var readFile = opts.readFile || fs.readFile;
var realpath = opts.realpath || defaultRealpath;
var readPkg = opts.readPkg || defaultReadPkg;
var packageIterator = opts.packageIterator;

var extensions = opts.extensions || ['.js'];
Expand Down Expand Up @@ -211,9 +226,10 @@ module.exports = function resolve(x, options, callback) {
// on err, ex is false
if (!ex) return loadpkg(path.dirname(dir), cb);

readFile(pkgfile, function (err, body) {
readPkg(readFile, pkgfile, function (err, pkgParam) {
if (err) cb(err);
try { var pkg = JSON.parse(body); } catch (jsonErr) {}

var pkg = pkgParam;

if (pkg && opts.packageFilter) {
pkg = opts.packageFilter(pkg, pkgfile, dir);
Expand All @@ -239,11 +255,10 @@ module.exports = function resolve(x, options, callback) {
if (err) return cb(err);
if (!ex) return loadAsFile(path.join(x, 'index'), fpkg, cb);

readFile(pkgfile, function (err, body) {
readPkg(readFile, pkgfile, function (err, pkgParam) {
if (err) return cb(err);
try {
var pkg = JSON.parse(body);
} catch (jsonErr) {}

var pkg = pkgParam;

if (pkg && opts.packageFilter) {
pkg = opts.packageFilter(pkg, pkgfile, pkgdir);
Expand Down
18 changes: 11 additions & 7 deletions lib/sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ var maybeRealpathSync = function maybeRealpathSync(realpathSync, x, opts) {
return x;
};

var defaultReadPkgSync = function defaultReadPkgSync(readFileSync, pkgfile) {
var body = readFileSync(pkgfile);
try {
var pkg = JSON.parse(body);
return pkg;
} catch (jsonErr) {}
};

var getPackageCandidates = function getPackageCandidates(x, start, opts) {
var dirs = nodeModulesPaths(start, opts, x);
for (var i = 0; i < dirs.length; i++) {
Expand All @@ -63,6 +71,7 @@ module.exports = function resolveSync(x, options) {
var isDirectory = opts.isDirectory || defaultIsDir;
var readFileSync = opts.readFileSync || fs.readFileSync;
var realpathSync = opts.realpathSync || defaultRealpathSync;
var readPkgSync = opts.readPkgSync || defaultReadPkgSync;
var packageIterator = opts.packageIterator;

var extensions = opts.extensions || ['.js'];
Expand Down Expand Up @@ -133,11 +142,7 @@ module.exports = function resolveSync(x, options) {
return loadpkg(path.dirname(dir));
}

var body = readFileSync(pkgfile);

try {
var pkg = JSON.parse(body);
} catch (jsonErr) {}
var pkg = readPkgSync(readFileSync, pkgfile);

if (pkg && opts.packageFilter) {
pkg = opts.packageFilter(pkg, pkgfile, dir);
Expand All @@ -150,8 +155,7 @@ module.exports = function resolveSync(x, options) {
var pkgfile = path.join(isDirectory(x) ? maybeRealpathSync(realpathSync, x, opts) : x, '/package.json');
if (isFile(pkgfile)) {
try {
var body = readFileSync(pkgfile, 'UTF8');
var pkg = JSON.parse(body);
var pkg = readPkgSync(readFileSync, pkgfile);
} catch (e) {}

if (pkg && opts.packageFilter) {
Expand Down
31 changes: 29 additions & 2 deletions readme.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,10 @@ options are:

* opts.realpath - function to asynchronously resolve a potential symlink to its real path

* opts.realpath - function to asynchronously resolve a potential symlink to its real path
* `opts.readPkg(readFile, pkgfile, cb)` - function to asynchronously read and parse a package.json file
* readFile - the passed `opts.readFile` or `fs.readFile` if not specified
* pkgfile - path to package.json
* cb - callback

* `opts.packageFilter(pkg, pkgfile, dir)` - transform the parsed package.json contents before looking at the "main" field
* pkg - package data
Expand Down Expand Up @@ -137,6 +140,19 @@ default `opts` values:
else cb(null, realPathErr ? file : realPath);
});
},
readPkg: function defaultReadPkg(readFile, pkgfile, cb) {
readFile(pkgfile, function (readFileErr, body) {
if (readFileErr) cb(readFileErr);
else {
try {
var pkg = JSON.parse(body);
cb(null, pkg);
} catch (jsonErr) {
cb(null);
}
}
});
},
moduleDirectory: 'node_modules',
preserveSymlinks: false
}
Expand All @@ -155,14 +171,18 @@ options are:

* opts.includeCoreModules - set to `false` to exclude node core modules (e.g. `fs`) from the search

* opts.readFile - how to read files synchronously
* opts.readFileSync - how to read files synchronously

* opts.isFile - function to synchronously test whether a file exists

* opts.isDirectory - function to synchronously test whether a file exists and is a directory

* opts.realpathSync - function to synchronously resolve a potential symlink to its real path

* `opts.readPkgSync(readFileSync, pkgfile)` - function to synchronously read and parse a package.json file
* readFileSync - the passed `opts.readFileSync` or `fs.readFileSync` if not specified
* pkgfile - path to package.json

* `opts.packageFilter(pkg, pkgfile, dir)` - transform the parsed package.json contents before looking at the "main" field
* pkg - package data
* pkgfile - path to package.json
Expand Down Expand Up @@ -231,6 +251,13 @@ default `opts` values:
}
return file;
},
readPkgSync: function readPkgSync(readFileSync, pkgfile) {
var body = readFileSync(pkgfile);
try {
var pkg = JSON.parse(body);
return pkg;
} catch (jsonErr) {}
},
moduleDirectory: 'node_modules',
preserveSymlinks: false
}
Expand Down
46 changes: 46 additions & 0 deletions test/mock.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,3 +237,49 @@ test('symlinked', function (t) {
t.equal(pkg, undefined);
});
});

test('readPkg', function (t) {
t.plan(2);

var files = {};
files[path.resolve('/foo/node_modules/bar/something-else.js')] = 'beep';
files[path.resolve('/foo/node_modules/bar/package.json')] = JSON.stringify({
main: './baz.js'
});

var dirs = {};
dirs[path.resolve('/foo')] = true;
dirs[path.resolve('/foo/node_modules')] = true;

function opts(basedir) {
return {
basedir: path.resolve(basedir),
isFile: function (file, cb) {
cb(null, Object.prototype.hasOwnProperty.call(files, path.resolve(file)));
},
isDirectory: function (dir, cb) {
cb(null, !!dirs[path.resolve(dir)]);
},
'package': { main: 'bar' },
readFile: function (file, cb) {
cb(null, files[path.resolve(file)]);
},
realpath: function (file, cb) {
cb(null, file);
},
readPkg: function (readFile, file, cb) {
if (file.indexOf(path.join('bar', 'package.json')) >= 0) {
cb(null, { main: './something-else.js' });
} else {
cb(null, JSON.parse(files[path.resolve(file)]));
}
}
};
}

resolve('bar', opts('/foo'), function (err, res, pkg) {
if (err) return t.fail(err);
t.equal(res, path.resolve('/foo/node_modules/bar/something-else.js'));
t.equal(pkg && pkg.main, './something-else.js');
});
});
45 changes: 45 additions & 0 deletions test/mock_sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,48 @@ test('symlinked', function (t) {
path.resolve('/foo/bar/symlinked/baz.js')
);
});

test('readPkgSync', function (t) {
t.plan(1);

var files = {};
files[path.resolve('/foo/node_modules/bar/something-else.js')] = 'beep';
files[path.resolve('/foo/node_modules/bar/package.json')] = JSON.stringify({
main: './baz.js'
});

var dirs = {};
dirs[path.resolve('/foo')] = true;
dirs[path.resolve('/foo/node_modules')] = true;

function opts(basedir) {
return {
basedir: path.resolve(basedir),
isFile: function (file) {
return Object.prototype.hasOwnProperty.call(files, path.resolve(file));
},
isDirectory: function (dir) {
return !!dirs[path.resolve(dir)];
},
readFileSync: function (file) {
return files[path.resolve(file)];
},
realpathSync: function (file) {
return file;
},
readPkgSync: function (readFileSync, file) {
if (file.indexOf(path.join('bar', 'package.json')) >= 0) {
return { main: './something-else.js' };
} else {
return JSON.parse(files[path.resolve(file)]);
}
}
};
}

t.equal(
resolve.sync('bar', opts('/foo')),
path.resolve('/foo/node_modules/bar/something-else.js')
);
});

0 comments on commit 98b6d92

Please sign in to comment.