Clean up the oopsie. Rebuild the blank exercises.

This commit is contained in:
Michael Frank
2021-05-09 00:39:21 +12:00
parent b984cb4c6f
commit d28d80c46f
1565 changed files with 27186 additions and 199003 deletions
+22 -5
View File
@@ -1,20 +1,37 @@
root = true
[*]
indent_style = tab
indent_size = 4
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 120
max_line_length = 200
[*.js]
block_comment_start = /*
block_comment = *
block_comment_end = */
[*.yml]
indent_size = 1
[package.json]
indent_style = tab
[lib/core.json]
indent_style = tab
[CHANGELOG.md]
indent_style = space
indent_size = 2
[*.json]
[{*.json,Makefile}]
max_line_length = off
[Makefile]
[test/{dotdot,resolver,module_dir,multirepo,node_path,pathfilter,precedence}/**/*]
indent_style = off
indent_size = off
max_line_length = off
insert_final_newline = off
+10 -1
View File
@@ -14,6 +14,7 @@
"func-style": 0,
"global-require": 0,
"id-length": [2, { "min": 1, "max": 30 }],
"max-lines-per-function": 0,
"max-nested-callbacks": 0,
"max-params": 0,
"max-statements-per-line": [2, { "max": 2 }],
@@ -26,5 +27,13 @@
"object-curly-newline": 0,
"operator-linebreak": [2, "before"],
"sort-keys": 0,
}
},
"overrides": [
{
"files": "test/resolver/nested_symlinks/mylib/*.js",
"rules": {
"no-throw-literal": 0,
},
},
],
}
-173
View File
@@ -1,173 +0,0 @@
language: node_js
os:
- linux
node_js:
- "8.8"
- "7.10"
- "6.11"
- "5.12"
- "4.8"
- "iojs-v3.3"
- "iojs-v2.5"
- "iojs-v1.8"
- "0.12"
- "0.10"
- "0.8"
before_install:
- 'nvm install-latest-npm'
install:
- 'if [ "${TRAVIS_NODE_VERSION}" = "0.6" ] || [ "${TRAVIS_NODE_VERSION}" = "0.9" ]; then nvm install --latest-npm 0.8 && npm install && nvm use "${TRAVIS_NODE_VERSION}"; else npm install; fi;'
script:
- 'if [ -n "${PRETEST-}" ]; then npm run pretest ; fi'
- 'if [ -n "${POSTTEST-}" ]; then npm run posttest ; fi'
- 'if [ -n "${COVERAGE-}" ]; then npm run coverage ; fi'
- 'if [ -n "${TEST-}" ]; then npm run tests-only ; fi'
sudo: false
env:
- TEST=true
matrix:
fast_finish: true
include:
- node_js: "node"
env: PRETEST=true
- node_js: "8.7"
env: TEST=true ALLOW_FAILURE=true
- node_js: "8.6"
env: TEST=true ALLOW_FAILURE=true
- node_js: "8.5"
env: TEST=true ALLOW_FAILURE=true
- node_js: "8.4"
env: TEST=true ALLOW_FAILURE=true
- node_js: "8.3"
env: TEST=true ALLOW_FAILURE=true
- node_js: "8.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "8.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "8.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.9"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.8"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.7"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.6"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.5"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.4"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.3"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.10"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.9"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.8"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.7"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.6"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.5"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.4"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.3"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.11"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.10"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.9"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.8"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.7"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.6"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.5"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.4"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.3"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "4.7"
env: TEST=true ALLOW_FAILURE=true
- node_js: "4.6"
env: TEST=true ALLOW_FAILURE=true
- node_js: "4.5"
env: TEST=true ALLOW_FAILURE=true
- node_js: "4.4"
env: TEST=true ALLOW_FAILURE=true
- node_js: "4.3"
env: TEST=true ALLOW_FAILURE=true
- node_js: "4.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "4.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "4.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v3.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v3.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v3.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v2.4"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v2.3"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v2.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v2.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v2.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v1.7"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v1.6"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v1.5"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v1.4"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v1.3"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v1.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v1.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v1.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "0.11"
env: TEST=true ALLOW_FAILURE=true
- node_js: "0.9"
env: TEST=true ALLOW_FAILURE=true
- node_js: "0.6"
env: TEST=true ALLOW_FAILURE=true
- node_js: "0.4"
env: TEST=true ALLOW_FAILURE=true
allow_failures:
- os: osx
- env: TEST=true ALLOW_FAILURE=true
+15 -12
View File
@@ -1,18 +1,21 @@
This software is released under the MIT license:
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
Copyright (c) 2012 James Halliday
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+38 -8
View File
@@ -4,6 +4,14 @@ build: off
environment:
matrix:
#- nodejs_version: "15"
- nodejs_version: "14"
- nodejs_version: "13"
- nodejs_version: "12"
- nodejs_version: "11"
- nodejs_version: "10"
- nodejs_version: "9"
- nodejs_version: "8"
- nodejs_version: "7"
- nodejs_version: "6"
- nodejs_version: "5"
@@ -18,6 +26,9 @@ environment:
matrix:
# fast_finish: true
allow_failures:
- nodejs_version: "5" # due to windows npm bug, registry-side
- nodejs_version: "0.8"
# platform: x86 # x64 has started failing on the registry side, around early November 2020
- nodejs_version: "0.6"
platform:
@@ -26,14 +37,33 @@ platform:
# Install scripts. (runs after repo cloning)
install:
# Get the latest stable version of Node.js or io.js
- ps: Install-Product node $env:nodejs_version $env:platform
- IF %nodejs_version% EQU 0.6 npm -g install npm@1.3
- IF %nodejs_version% EQU 0.8 npm -g install npm@2
- set PATH=%APPDATA%\npm;%PATH%
#- IF %nodejs_version% NEQ 0.6 AND %nodejs_version% NEQ 0.8 npm -g install npm
# install modules
- npm install
# Fix symlinks in working copy (see https://github.com/appveyor/ci/issues/650#issuecomment-186592582) / https://github.com/charleskorn/batect/commit/d08986802ec43086902958c4ee7e57ff3e71dbef
- git config core.symlinks true
- git reset --hard
# Get the latest stable version of Node.js or io.js
- ps: if ($env:nodejs_version -ne '0.6') { Install-Product node $env:nodejs_version $env:platform }
- ps: Update-NodeJsInstallation (Get-NodeJsLatestBuild $env:nodejs_version) $env:platform
- IF %nodejs_version% EQU 0.6 npm config set strict-ssl false && npm -g install npm@1.3
- IF %nodejs_version% EQU 0.8 npm config set strict-ssl false && npm -g install npm@1.4.28 && npm install -g npm@4.5
- IF %nodejs_version% EQU 1 npm -g install npm@2.9
- IF %nodejs_version% EQU 2 npm -g install npm@4
- IF %nodejs_version% EQU 3 npm -g install npm@4
- IF %nodejs_version% EQU 4 npm -g install npm@5.3
- IF %nodejs_version% EQU 5 npm -g install npm@5.3
- IF %nodejs_version% EQU 6 npm -g install npm@6.9
- IF %nodejs_version% EQU 7 npm -g install npm@6
- IF %nodejs_version% EQU 8 npm -g install npm@6
- IF %nodejs_version% EQU 9 npm -g install npm@6.9
- IF %nodejs_version% EQU 10 npm -g install npm@7
- IF %nodejs_version% EQU 11 npm -g install npm@7
- IF %nodejs_version% EQU 12 npm -g install npm@7
- IF %nodejs_version% EQU 13 npm -g install npm@7
- IF %nodejs_version% EQU 14 npm -g install npm@7
- IF %nodejs_version% EQU 15 npm -g install npm@7
- set PATH=%APPDATA%\npm;%PATH%
#- IF %nodejs_version% NEQ 0.6 AND %nodejs_version% NEQ 0.8 npm -g install npm
# install modules
- npm install
# Post-install test scripts.
test_script:
+2 -4
View File
@@ -1,8 +1,6 @@
var core = require('./lib/core');
var async = require('./lib/async');
async.core = core;
async.isCore = function isCore(x) { return core[x]; };
async.core = require('./lib/core');
async.isCore = require('./lib/is-core');
async.sync = require('./lib/sync');
exports = async;
module.exports = async;
+194 -77
View File
@@ -1,13 +1,73 @@
var core = require('./core');
var fs = require('fs');
var path = require('path');
var caller = require('./caller.js');
var nodeModulesPaths = require('./node-modules-paths.js');
var caller = require('./caller');
var nodeModulesPaths = require('./node-modules-paths');
var normalizeOptions = require('./normalize-options');
var isCore = require('is-core-module');
var realpathFS = fs.realpath && typeof fs.realpath.native === 'function' ? fs.realpath.native : fs.realpath;
var defaultIsFile = function isFile(file, cb) {
fs.stat(file, function (err, stat) {
if (!err) {
return cb(null, stat.isFile() || stat.isFIFO());
}
if (err.code === 'ENOENT' || err.code === 'ENOTDIR') return cb(null, false);
return cb(err);
});
};
var defaultIsDir = function isDirectory(dir, cb) {
fs.stat(dir, function (err, stat) {
if (!err) {
return cb(null, stat.isDirectory());
}
if (err.code === 'ENOENT' || err.code === 'ENOTDIR') return cb(null, false);
return cb(err);
});
};
var defaultRealpath = function realpath(x, cb) {
realpathFS(x, function (realpathErr, realPath) {
if (realpathErr && realpathErr.code !== 'ENOENT') cb(realpathErr);
else cb(null, realpathErr ? x : realPath);
});
};
var maybeRealpath = function maybeRealpath(realpath, x, opts, cb) {
if (opts && opts.preserveSymlinks === false) {
realpath(x, cb);
} else {
cb(null, x);
}
};
var defaultReadPackage = function defaultReadPackage(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++) {
dirs[i] = path.join(dirs[i], x);
}
return dirs;
};
module.exports = function resolve(x, options, callback) {
var cb = callback;
var opts = options || {};
if (typeof opts === 'function') {
var opts = options;
if (typeof options === 'function') {
cb = opts;
opts = {};
}
@@ -18,47 +78,84 @@ module.exports = function resolve(x, options, callback) {
});
}
var isFile = opts.isFile || function (file, cb) {
fs.stat(file, function (err, stat) {
if (!err) {
return cb(null, stat.isFile() || stat.isFIFO());
}
if (err.code === 'ENOENT' || err.code === 'ENOTDIR') return cb(null, false);
return cb(err);
});
};
opts = normalizeOptions(x, opts);
var isFile = opts.isFile || defaultIsFile;
var isDirectory = opts.isDirectory || defaultIsDir;
var readFile = opts.readFile || fs.readFile;
var realpath = opts.realpath || defaultRealpath;
var readPackage = opts.readPackage || defaultReadPackage;
if (opts.readFile && opts.readPackage) {
var conflictErr = new TypeError('`readFile` and `readPackage` are mutually exclusive.');
return process.nextTick(function () {
cb(conflictErr);
});
}
var packageIterator = opts.packageIterator;
var extensions = opts.extensions || ['.js'];
var y = opts.basedir || path.dirname(caller());
var includeCoreModules = opts.includeCoreModules !== false;
var basedir = opts.basedir || path.dirname(caller());
var parent = opts.filename || basedir;
opts.paths = opts.paths || [];
if (/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/.test(x)) {
var res = path.resolve(y, x);
if (x === '..' || x.slice(-1) === '/') res += '/';
if (/\/$/.test(x) && res === y) {
loadAsDirectory(res, opts.package, onfile);
} else loadAsFile(res, opts.package, onfile);
} else loadNodeModules(x, y, function (err, n, pkg) {
if (err) cb(err);
else if (n) cb(null, n, pkg);
else if (core[x]) return cb(null, x);
else {
var moduleError = new Error("Cannot find module '" + x + "' from '" + y + "'");
moduleError.code = 'MODULE_NOT_FOUND';
cb(moduleError);
// ensure that `basedir` is an absolute path at this point, resolving against the process' current working directory
var absoluteStart = path.resolve(basedir);
maybeRealpath(
realpath,
absoluteStart,
opts,
function (err, realStart) {
if (err) cb(err);
else init(realStart);
}
});
);
var res;
function init(basedir) {
if ((/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/).test(x)) {
res = path.resolve(basedir, x);
if (x === '.' || x === '..' || x.slice(-1) === '/') res += '/';
if ((/\/$/).test(x) && res === basedir) {
loadAsDirectory(res, opts.package, onfile);
} else loadAsFile(res, opts.package, onfile);
} else if (includeCoreModules && isCore(x)) {
return cb(null, x);
} else loadNodeModules(x, basedir, function (err, n, pkg) {
if (err) cb(err);
else if (n) {
return maybeRealpath(realpath, n, opts, function (err, realN) {
if (err) {
cb(err);
} else {
cb(null, realN, pkg);
}
});
} else {
var moduleError = new Error("Cannot find module '" + x + "' from '" + parent + "'");
moduleError.code = 'MODULE_NOT_FOUND';
cb(moduleError);
}
});
}
function onfile(err, m, pkg) {
if (err) cb(err);
else if (m) cb(null, m, pkg);
else loadAsDirectory(res, function (err, d, pkg) {
if (err) cb(err);
else if (d) cb(null, d, pkg);
else {
var moduleError = new Error("Cannot find module '" + x + "' from '" + y + "'");
else if (d) {
maybeRealpath(realpath, d, opts, function (err, realD) {
if (err) {
cb(err);
} else {
cb(null, realD, pkg);
}
});
} else {
var moduleError = new Error("Cannot find module '" + x + "' from '" + parent + "'");
moduleError.code = 'MODULE_NOT_FOUND';
cb(moduleError);
}
@@ -112,21 +209,25 @@ module.exports = function resolve(x, options, callback) {
if (process.platform === 'win32' && (/^\w:[/\\]*$/).test(dir)) {
return cb(null);
}
if (/[/\\]node_modules[/\\]*$/.test(dir)) return cb(null);
if ((/[/\\]node_modules[/\\]*$/).test(dir)) return cb(null);
var pkgfile = path.join(dir, 'package.json');
isFile(pkgfile, function (err, ex) {
// on err, ex is false
if (!ex) return loadpkg(path.dirname(dir), cb);
maybeRealpath(realpath, dir, opts, function (unwrapErr, pkgdir) {
if (unwrapErr) return loadpkg(path.dirname(dir), cb);
var pkgfile = path.join(pkgdir, 'package.json');
isFile(pkgfile, function (err, ex) {
// on err, ex is false
if (!ex) return loadpkg(path.dirname(dir), cb);
readFile(pkgfile, function (err, body) {
if (err) cb(err);
try { var pkg = JSON.parse(body); } catch (jsonErr) {}
readPackage(readFile, pkgfile, function (err, pkgParam) {
if (err) cb(err);
if (pkg && opts.packageFilter) {
pkg = opts.packageFilter(pkg, pkgfile);
}
cb(null, pkg, dir);
var pkg = pkgParam;
if (pkg && opts.packageFilter) {
pkg = opts.packageFilter(pkg, pkgfile);
}
cb(null, pkg, dir);
});
});
});
}
@@ -139,41 +240,48 @@ module.exports = function resolve(x, options, callback) {
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'), fpkg, cb);
readFile(pkgfile, function (err, body) {
maybeRealpath(realpath, x, opts, function (unwrapErr, pkgdir) {
if (unwrapErr) return cb(unwrapErr);
var pkgfile = path.join(pkgdir, 'package.json');
isFile(pkgfile, function (err, ex) {
if (err) return cb(err);
try {
var pkg = JSON.parse(body);
} catch (jsonErr) {}
if (!ex) return loadAsFile(path.join(x, 'index'), fpkg, cb);
if (opts.packageFilter) {
pkg = opts.packageFilter(pkg, pkgfile);
}
readPackage(readFile, pkgfile, function (err, pkgParam) {
if (err) return cb(err);
if (pkg.main) {
if (pkg.main === '.' || pkg.main === './') {
pkg.main = 'index';
var pkg = pkgParam;
if (pkg && opts.packageFilter) {
pkg = opts.packageFilter(pkg, pkgfile);
}
loadAsFile(path.resolve(x, pkg.main), pkg, function (err, m, pkg) {
if (err) return cb(err);
if (m) return cb(null, m, pkg);
if (!pkg) return loadAsFile(path.join(x, 'index'), pkg, cb);
var dir = path.resolve(x, pkg.main);
loadAsDirectory(dir, pkg, function (err, n, pkg) {
if (pkg && pkg.main) {
if (typeof pkg.main !== 'string') {
var mainError = new TypeError('package “' + pkg.name + '” `main` must be a string');
mainError.code = 'INVALID_PACKAGE_MAIN';
return cb(mainError);
}
if (pkg.main === '.' || pkg.main === './') {
pkg.main = 'index';
}
loadAsFile(path.resolve(x, pkg.main), pkg, function (err, m, pkg) {
if (err) return cb(err);
if (n) return cb(null, n, pkg);
loadAsFile(path.join(x, 'index'), pkg, cb);
});
});
return;
}
if (m) return cb(null, m, pkg);
if (!pkg) return loadAsFile(path.join(x, 'index'), pkg, cb);
loadAsFile(path.join(x, '/index'), pkg, cb);
var dir = path.resolve(x, pkg.main);
loadAsDirectory(dir, pkg, function (err, n, pkg) {
if (err) return cb(err);
if (n) return cb(null, n, pkg);
loadAsFile(path.join(x, 'index'), pkg, cb);
});
});
return;
}
loadAsFile(path.join(x, '/index'), pkg, cb);
});
});
});
}
@@ -182,13 +290,18 @@ module.exports = function resolve(x, options, callback) {
if (dirs.length === 0) return cb(null, undefined);
var dir = dirs[0];
var file = path.join(dir, x);
loadAsFile(file, undefined, onfile);
isDirectory(path.dirname(dir), isdir);
function isdir(err, isdir) {
if (err) return cb(err);
if (!isdir) return processDirs(cb, dirs.slice(1));
loadAsFile(dir, opts.package, onfile);
}
function onfile(err, m, pkg) {
if (err) return cb(err);
if (m) return cb(null, m, pkg);
loadAsDirectory(path.join(dir, x), undefined, ondir);
loadAsDirectory(dir, opts.package, ondir);
}
function ondir(err, n, pkg) {
@@ -198,6 +311,10 @@ module.exports = function resolve(x, options, callback) {
}
}
function loadNodeModules(x, start, cb) {
processDirs(cb, nodeModulesPaths(start, opts));
var thunk = function () { return getPackageCandidates(x, start, opts); };
processDirs(
cb,
packageIterator ? packageIterator(x, start, thunk, opts) : thunk()
);
}
};
+26 -7
View File
@@ -1,14 +1,13 @@
var current = (process.versions && process.versions.node && process.versions.node.split('.')) || [];
function versionIncluded(specifier) {
if (specifier === true) { return true; }
function specifierIncluded(specifier) {
var parts = specifier.split(' ');
var op = parts[0];
var versionParts = parts[1].split('.');
var op = parts.length > 1 ? parts[0] : '=';
var versionParts = (parts.length > 1 ? parts[1] : parts[0]).split('.');
for (var i = 0; i < 3; ++i) {
var cur = Number(current[i] || 0);
var ver = Number(versionParts[i] || 0);
var cur = parseInt(current[i] || 0, 10);
var ver = parseInt(versionParts[i] || 0, 10);
if (cur === ver) {
continue; // eslint-disable-line no-restricted-syntax, no-continue
}
@@ -20,7 +19,27 @@ function versionIncluded(specifier) {
return false;
}
}
return false;
return op === '>=';
}
function matchesRange(range) {
var specifiers = range.split(/ ?&& ?/);
if (specifiers.length === 0) { return false; }
for (var i = 0; i < specifiers.length; ++i) {
if (!specifierIncluded(specifiers[i])) { return false; }
}
return true;
}
function versionIncluded(specifierValue) {
if (typeof specifierValue === 'boolean') { return specifierValue; }
if (specifierValue && typeof specifierValue === 'object') {
for (var i = 0; i < specifierValue.length; ++i) {
if (matchesRange(specifierValue[i])) { return true; }
}
return false;
}
return matchesRange(specifierValue);
}
var data = require('./core.json');
+81 -41
View File
@@ -1,43 +1,83 @@
{
"assert": true,
"buffer_ieee754": "< 0.9.7",
"buffer": true,
"child_process": true,
"cluster": true,
"console": true,
"constants": true,
"crypto": true,
"_debugger": "< 8",
"dgram": true,
"dns": true,
"domain": true,
"events": true,
"freelist": "< 6",
"fs": true,
"http": true,
"http2": ">= 8.8",
"https": true,
"_http_server": ">= 0.11",
"_linklist": "< 8",
"module": true,
"net": true,
"os": true,
"path": true,
"perf_hooks": ">= 8.5",
"process": ">= 1",
"punycode": true,
"querystring": true,
"readline": true,
"repl": true,
"stream": true,
"string_decoder": true,
"sys": true,
"timers": true,
"tls": true,
"tty": true,
"url": true,
"util": true,
"v8": ">= 1",
"vm": true,
"zlib": true
"assert": true,
"assert/strict": ">= 15",
"async_hooks": ">= 8",
"buffer_ieee754": "< 0.9.7",
"buffer": true,
"child_process": true,
"cluster": true,
"console": true,
"constants": true,
"crypto": true,
"_debug_agent": ">= 1 && < 8",
"_debugger": "< 8",
"dgram": true,
"diagnostics_channel": ">= 15.1",
"dns": true,
"dns/promises": ">= 15",
"domain": ">= 0.7.12",
"events": true,
"freelist": "< 6",
"fs": true,
"fs/promises": [">= 10 && < 10.1", ">= 14"],
"_http_agent": ">= 0.11.1",
"_http_client": ">= 0.11.1",
"_http_common": ">= 0.11.1",
"_http_incoming": ">= 0.11.1",
"_http_outgoing": ">= 0.11.1",
"_http_server": ">= 0.11.1",
"http": true,
"http2": ">= 8.8",
"https": true,
"inspector": ">= 8.0.0",
"_linklist": "< 8",
"module": true,
"net": true,
"node-inspect/lib/_inspect": ">= 7.6.0 && < 12",
"node-inspect/lib/internal/inspect_client": ">= 7.6.0 && < 12",
"node-inspect/lib/internal/inspect_repl": ">= 7.6.0 && < 12",
"os": true,
"path": true,
"path/posix": ">= 15.3",
"path/win32": ">= 15.3",
"perf_hooks": ">= 8.5",
"process": ">= 1",
"punycode": true,
"querystring": true,
"readline": true,
"repl": true,
"smalloc": ">= 0.11.5 && < 3",
"_stream_duplex": ">= 0.9.4",
"_stream_transform": ">= 0.9.4",
"_stream_wrap": ">= 1.4.1",
"_stream_passthrough": ">= 0.9.4",
"_stream_readable": ">= 0.9.4",
"_stream_writable": ">= 0.9.4",
"stream": true,
"stream/promises": ">= 15",
"string_decoder": true,
"sys": [">= 0.6 && < 0.7", ">= 0.8"],
"timers": true,
"timers/promises": ">= 15",
"_tls_common": ">= 0.11.13",
"_tls_legacy": ">= 0.11.3 && < 10",
"_tls_wrap": ">= 0.11.3",
"tls": true,
"trace_events": ">= 10",
"tty": true,
"url": true,
"util": true,
"util/types": ">= 15.3",
"v8/tools/arguments": ">= 10 && < 12",
"v8/tools/codemap": [">= 4.4.0 && < 5", ">= 5.2.0 && < 12"],
"v8/tools/consarray": [">= 4.4.0 && < 5", ">= 5.2.0 && < 12"],
"v8/tools/csvparser": [">= 4.4.0 && < 5", ">= 5.2.0 && < 12"],
"v8/tools/logreader": [">= 4.4.0 && < 5", ">= 5.2.0 && < 12"],
"v8/tools/profile_view": [">= 4.4.0 && < 5", ">= 5.2.0 && < 12"],
"v8/tools/splaytree": [">= 4.4.0 && < 5", ">= 5.2.0 && < 12"],
"v8": ">= 1",
"vm": true,
"wasi": ">= 13.4 && < 13.5",
"worker_threads": ">= 11.7",
"zlib": true
}
+21 -24
View File
@@ -1,30 +1,11 @@
var path = require('path');
var fs = require('fs');
var parse = path.parse || require('path-parse');
module.exports = function nodeModulesPaths(start, opts) {
var modules = opts && opts.moduleDirectory
? [].concat(opts.moduleDirectory)
: ['node_modules'];
// ensure that `start` is an absolute path at this point,
// resolving against the process' current working directory
var absoluteStart = path.resolve(start);
if (opts && opts.preserveSymlinks === false) {
try {
absoluteStart = fs.realpathSync(absoluteStart);
} catch (err) {
if (err.code !== 'ENOENT') {
throw err;
}
}
}
var getNodeModulesDirs = function getNodeModulesDirs(absoluteStart, modules) {
var prefix = '/';
if (/^([A-Za-z]:)/.test(absoluteStart)) {
if ((/^([A-Za-z]:)/).test(absoluteStart)) {
prefix = '';
} else if (/^\\\\/.test(absoluteStart)) {
} else if ((/^\\\\/).test(absoluteStart)) {
prefix = '\\\\';
}
@@ -35,11 +16,27 @@ module.exports = function nodeModulesPaths(start, opts) {
parsed = parse(parsed.dir);
}
var dirs = paths.reduce(function (dirs, aPath) {
return paths.reduce(function (dirs, aPath) {
return dirs.concat(modules.map(function (moduleDir) {
return path.join(prefix, aPath, moduleDir);
return path.resolve(prefix, aPath, moduleDir);
}));
}, []);
};
module.exports = function nodeModulesPaths(start, opts, request) {
var modules = opts && opts.moduleDirectory
? [].concat(opts.moduleDirectory)
: ['node_modules'];
if (opts && typeof opts.paths === 'function') {
return opts.paths(
request,
start,
function () { return getNodeModulesDirs(start, modules); },
opts
);
}
var dirs = getNodeModulesDirs(start, modules);
return opts && opts.paths ? dirs.concat(opts.paths) : dirs;
};
+147 -41
View File
@@ -1,47 +1,119 @@
var core = require('./core');
var isCore = require('is-core-module');
var fs = require('fs');
var path = require('path');
var caller = require('./caller.js');
var nodeModulesPaths = require('./node-modules-paths.js');
var caller = require('./caller');
var nodeModulesPaths = require('./node-modules-paths');
var normalizeOptions = require('./normalize-options');
module.exports = function (x, options) {
var realpathFS = fs.realpathSync && typeof fs.realpathSync.native === 'function' ? fs.realpathSync.native : fs.realpathSync;
var defaultIsFile = function isFile(file) {
try {
var stat = fs.statSync(file);
} catch (e) {
if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false;
throw e;
}
return stat.isFile() || stat.isFIFO();
};
var defaultIsDir = function isDirectory(dir) {
try {
var stat = fs.statSync(dir);
} catch (e) {
if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false;
throw e;
}
return stat.isDirectory();
};
var defaultRealpathSync = function realpathSync(x) {
try {
return realpathFS(x);
} catch (realpathErr) {
if (realpathErr.code !== 'ENOENT') {
throw realpathErr;
}
}
return x;
};
var maybeRealpathSync = function maybeRealpathSync(realpathSync, x, opts) {
if (opts && opts.preserveSymlinks === false) {
return realpathSync(x);
}
return x;
};
var defaultReadPackageSync = function defaultReadPackageSync(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++) {
dirs[i] = path.join(dirs[i], x);
}
return dirs;
};
module.exports = function resolveSync(x, options) {
if (typeof x !== 'string') {
throw new TypeError('Path must be a string.');
}
var opts = options || {};
var isFile = opts.isFile || function (file) {
try {
var stat = fs.statSync(file);
} catch (e) {
if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false;
throw e;
}
return stat.isFile() || stat.isFIFO();
};
var opts = normalizeOptions(x, options);
var isFile = opts.isFile || defaultIsFile;
var readFileSync = opts.readFileSync || fs.readFileSync;
var isDirectory = opts.isDirectory || defaultIsDir;
var realpathSync = opts.realpathSync || defaultRealpathSync;
var readPackageSync = opts.readPackageSync || defaultReadPackageSync;
if (opts.readFileSync && opts.readPackageSync) {
throw new TypeError('`readFileSync` and `readPackageSync` are mutually exclusive.');
}
var packageIterator = opts.packageIterator;
var extensions = opts.extensions || ['.js'];
var y = opts.basedir || path.dirname(caller());
var includeCoreModules = opts.includeCoreModules !== false;
var basedir = opts.basedir || path.dirname(caller());
var parent = opts.filename || basedir;
opts.paths = opts.paths || [];
if (/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/.test(x)) {
var res = path.resolve(y, x);
if (x === '..' || x.slice(-1) === '/') res += '/';
// ensure that `basedir` is an absolute path at this point, resolving against the process' current working directory
var absoluteStart = maybeRealpathSync(realpathSync, path.resolve(basedir), opts);
if ((/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/).test(x)) {
var res = path.resolve(absoluteStart, x);
if (x === '.' || x === '..' || x.slice(-1) === '/') res += '/';
var m = loadAsFileSync(res) || loadAsDirectorySync(res);
if (m) return m;
if (m) return maybeRealpathSync(realpathSync, m, opts);
} else if (includeCoreModules && isCore(x)) {
return x;
} else {
var n = loadNodeModulesSync(x, y);
if (n) return n;
var n = loadNodeModulesSync(x, absoluteStart);
if (n) return maybeRealpathSync(realpathSync, n, opts);
}
if (core[x]) return x;
var err = new Error("Cannot find module '" + x + "' from '" + y + "'");
var err = new Error("Cannot find module '" + x + "' from '" + parent + "'");
err.code = 'MODULE_NOT_FOUND';
throw err;
function loadAsFileSync(x) {
var pkg = loadpkg(path.dirname(x));
if (pkg && pkg.dir && pkg.pkg && opts.pathFilter) {
var rfile = path.relative(pkg.dir, x);
var r = opts.pathFilter(pkg.pkg, x, rfile);
if (r) {
x = path.resolve(pkg.dir, r); // eslint-disable-line no-param-reassign
}
}
if (isFile(x)) {
return x;
}
@@ -54,40 +126,74 @@ module.exports = function (x, options) {
}
}
function loadpkg(dir) {
if (dir === '' || dir === '/') return;
if (process.platform === 'win32' && (/^\w:[/\\]*$/).test(dir)) {
return;
}
if ((/[/\\]node_modules[/\\]*$/).test(dir)) return;
var pkgfile = path.join(maybeRealpathSync(realpathSync, dir, opts), 'package.json');
if (!isFile(pkgfile)) {
return loadpkg(path.dirname(dir));
}
var pkg = readPackageSync(readFileSync, pkgfile);
if (pkg && opts.packageFilter) {
// v2 will pass pkgfile
pkg = opts.packageFilter(pkg, /*pkgfile,*/ dir); // eslint-disable-line spaced-comment
}
return { pkg: pkg, dir: dir };
}
function loadAsDirectorySync(x) {
var pkgfile = path.join(x, '/package.json');
var pkgfile = path.join(maybeRealpathSync(realpathSync, x, opts), '/package.json');
if (isFile(pkgfile)) {
try {
var body = readFileSync(pkgfile, 'UTF8');
var pkg = JSON.parse(body);
var pkg = readPackageSync(readFileSync, pkgfile);
} catch (e) {}
if (opts.packageFilter) {
pkg = opts.packageFilter(pkg, x);
if (pkg && opts.packageFilter) {
// v2 will pass pkgfile
pkg = opts.packageFilter(pkg, /*pkgfile,*/ x); // eslint-disable-line spaced-comment
}
if (pkg && pkg.main) {
if (typeof pkg.main !== 'string') {
var mainError = new TypeError('package “' + pkg.name + '” `main` must be a string');
mainError.code = 'INVALID_PACKAGE_MAIN';
throw mainError;
}
if (pkg.main) {
if (pkg.main === '.' || pkg.main === './') {
pkg.main = 'index';
}
if (pkg.main === '.' || pkg.main === './') {
pkg.main = 'index';
}
try {
var m = loadAsFileSync(path.resolve(x, pkg.main));
if (m) return m;
var n = loadAsDirectorySync(path.resolve(x, pkg.main));
if (n) return n;
}
} catch (e) {}
} catch (e) {}
}
}
return loadAsFileSync(path.join(x, '/index'));
}
function loadNodeModulesSync(x, start) {
var dirs = nodeModulesPaths(start, opts);
var thunk = function () { return getPackageCandidates(x, start, opts); };
var dirs = packageIterator ? packageIterator(x, start, thunk, opts) : thunk();
for (var i = 0; i < dirs.length; i++) {
var dir = dirs[i];
var m = loadAsFileSync(path.join(dir, '/', x));
if (m) return m;
var n = loadAsDirectorySync(path.join(dir, '/', x));
if (n) return n;
if (isDirectory(path.dirname(dir))) {
var m = loadAsFileSync(dir);
if (m) return m;
var n = loadAsDirectorySync(dir);
if (n) return n;
}
}
}
};
+35 -23
View File
@@ -1,50 +1,58 @@
{
"_from": "resolve@^1.2.0",
"_id": "resolve@1.5.0",
"_from": "resolve@^1.18.1",
"_id": "resolve@1.20.0",
"_inBundle": false,
"_integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==",
"_integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
"_location": "/resolve",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "resolve@^1.2.0",
"raw": "resolve@^1.18.1",
"name": "resolve",
"escapedName": "resolve",
"rawSpec": "^1.2.0",
"rawSpec": "^1.18.1",
"saveSpec": null,
"fetchSpec": "^1.2.0"
"fetchSpec": "^1.18.1"
},
"_requiredBy": [
"/eslint-import-resolver-node"
"/jest-resolve",
"/normalize-package-data"
],
"_resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz",
"_shasum": "1f09acce796c9a762579f31b2c1cc4c3cddf9f36",
"_spec": "resolve@^1.2.0",
"_where": "/Users/cloyd/coderrr/odin/javascript-exercises/node_modules/eslint-import-resolver-node",
"_resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
"_shasum": "629a013fb3f70755d6f0b7935cc1c2c5378b1975",
"_spec": "resolve@^1.18.1",
"_where": "/home/michael/projects/javascript-exercises/node_modules/jest-resolve",
"author": {
"name": "James Halliday",
"email": "mail@substack.net",
"url": "http://substack.net"
},
"bugs": {
"url": "https://github.com/browserify/node-resolve/issues"
"url": "https://github.com/browserify/resolve/issues"
},
"bundleDependencies": false,
"dependencies": {
"path-parse": "^1.0.5"
"is-core-module": "^2.2.0",
"path-parse": "^1.0.6"
},
"deprecated": false,
"description": "resolve like require.resolve() on behalf of files asynchronously and synchronously",
"devDependencies": {
"@ljharb/eslint-config": "^12.2.1",
"eslint": "^4.9.0",
"object-keys": "^1.0.11",
"safe-publish-latest": "^1.1.1",
"@ljharb/eslint-config": "^17.5.1",
"array.prototype.map": "^1.0.3",
"aud": "^1.1.4",
"eclint": "^2.8.1",
"eslint": "^7.19.0",
"object-keys": "^1.1.1",
"safe-publish-latest": "^1.1.4",
"tap": "0.4.13",
"tape": "^4.8.0"
"tape": "^5.1.1"
},
"homepage": "https://github.com/browserify/node-resolve#readme",
"funding": {
"url": "https://github.com/sponsors/ljharb"
},
"homepage": "https://github.com/browserify/resolve#readme",
"keywords": [
"resolve",
"require",
@@ -56,14 +64,18 @@
"name": "resolve",
"repository": {
"type": "git",
"url": "git://github.com/browserify/node-resolve.git"
"url": "git://github.com/browserify/resolve.git"
},
"scripts": {
"lint": "eslint .",
"prepublish": "safe-publish-latest",
"lint": "eslint --ext=js,mjs .",
"posttest": "npm run test:multirepo && aud --production",
"prelint": "eclint check '**/*'",
"prepublish": "safe-publish-latest && cp node_modules/is-core-module/core.json ./lib/ ||:",
"pretest": "npm run lint",
"pretests-only": "cd ./test/resolver/nested_symlinks && node mylib/sync && node mylib/async",
"test": "npm run --silent tests-only",
"test:multirepo": "cd ./test/resolver/multirepo && npm install && npm test",
"tests-only": "tape test/*.js"
},
"version": "1.5.0"
"version": "1.20.0"
}
+153 -34
View File
@@ -5,17 +5,17 @@ algorithm](https://nodejs.org/api/modules.html#modules_all_together)
such that you can `require.resolve()` on behalf of a file asynchronously and
synchronously
[![build status](https://secure.travis-ci.org/browserify/node-resolve.png)](http://travis-ci.org/browserify/node-resolve)
[![build status](https://secure.travis-ci.org/browserify/resolve.png)](http://travis-ci.org/browserify/resolve)
# example
asynchronously resolve:
``` js
```js
var resolve = require('resolve');
resolve('tap', { basedir: __dirname }, function (err, res) {
if (err) console.error(err)
else console.log(res)
if (err) console.error(err);
else console.log(res);
});
```
@@ -26,7 +26,7 @@ $ node example/async.js
synchronously resolve:
``` js
```js
var resolve = require('resolve');
var res = resolve.sync('tap', { basedir: __dirname });
console.log(res);
@@ -39,10 +39,16 @@ $ node example/sync.js
# methods
``` js
var resolve = require('resolve')
```js
var resolve = require('resolve');
```
For both the synchronous and asynchronous methods, errors may have any of the following `err.code` values:
- `MODULE_NOT_FOUND`: the given path string (`id`) could not be resolved to a module
- `INVALID_BASEDIR`: the specified `opts.basedir` doesn't exist, or is not a directory
- `INVALID_PACKAGE_MAIN`: a `package.json` was encountered with an invalid `main` property (eg. not a string)
## resolve(id, opts={}, cb)
Asynchronously resolve the module path string `id` into `cb(err, res [, pkg])`, where `pkg` (if defined) is the data from `package.json`.
@@ -55,21 +61,45 @@ options are:
* opts.extensions - array of file extensions to search in order
* opts.includeCoreModules - set to `false` to exclude node core modules (e.g. `fs`) from the search
* opts.readFile - how to read files asynchronously
* opts.isFile - function to asynchronously test whether a file exists
* opts.packageFilter - transform the parsed package.json contents before looking
at the "main" field
* opts.isDirectory - function to asynchronously test whether a directory exists
* opts.pathFilter(pkg, path, relativePath) - transform a path within a package
* opts.realpath - function to asynchronously resolve a potential symlink to its real path
* `opts.readPackage(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
* pkgfile - path to package.json
* dir - directory for package.json
* `opts.pathFilter(pkg, path, relativePath)` - transform a path within a package
* pkg - package data
* path - the path being resolved
* relativePath - the path relative from the package.json location
* returns - a relative path that will be joined from the package.json location
* opts.paths - require.paths array to use if nothing is found on the normal
node_modules recursive walk (probably don't use this)
* opts.paths - require.paths array to use if nothing is found on the normal `node_modules` recursive walk (probably don't use this)
For advanced users, `paths` can also be a `opts.paths(request, start, opts)` function
* request - the import specifier being resolved
* start - lookup path
* getNodeModulesDirs - a thunk (no-argument function) that returns the paths using standard `node_modules` resolution
* opts - the resolution options
* `opts.packageIterator(request, start, opts)` - return the list of candidate paths where the packages sources may be found (probably don't use this)
* request - the import specifier being resolved
* start - lookup path
* getPackageCandidates - a thunk (no-argument function) that returns the paths using standard `node_modules` resolution
* opts - the resolution options
* opts.moduleDirectory - directory (or directories) in which to recursively look for modules. default: `"node_modules"`
@@ -80,17 +110,49 @@ This is the way Node resolves dependencies when executed with the [--preserve-sy
default `opts` values:
``` javascript
```js
{
paths: [],
basedir: __dirname,
extensions: [ '.js' ],
extensions: ['.js'],
includeCoreModules: true,
readFile: fs.readFile,
isFile: function (file, cb) {
isFile: function isFile(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.isFile())
if (!err) {
return cb(null, stat.isFile() || stat.isFIFO());
}
if (err.code === 'ENOENT' || err.code === 'ENOTDIR') return cb(null, false);
return cb(err);
});
},
isDirectory: function isDirectory(dir, cb) {
fs.stat(dir, function (err, stat) {
if (!err) {
return cb(null, stat.isDirectory());
}
if (err.code === 'ENOENT' || err.code === 'ENOTDIR') return cb(null, false);
return cb(err);
});
},
realpath: function realpath(file, cb) {
var realpath = typeof fs.realpath.native === 'function' ? fs.realpath.native : fs.realpath;
realpath(file, function (realPathErr, realPath) {
if (realPathErr && realPathErr.code !== 'ENOENT') cb(realPathErr);
else cb(null, realPathErr ? file : realPath);
});
},
readPackage: function defaultReadPackage(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',
@@ -109,15 +171,43 @@ options are:
* opts.extensions - array of file extensions to search in order
* opts.readFile - how to read files synchronously
* opts.includeCoreModules - set to `false` to exclude node core modules (e.g. `fs`) from the search
* opts.readFileSync - how to read files synchronously
* opts.isFile - function to synchronously test whether a file exists
* `opts.packageFilter(pkg, pkgfile)` - transform the parsed package.json
* contents before looking at the "main" field
* opts.isDirectory - function to synchronously test whether a directory exists
* opts.paths - require.paths array to use if nothing is found on the normal
node_modules recursive walk (probably don't use this)
* opts.realpathSync - function to synchronously resolve a potential symlink to its real path
* `opts.readPackageSync(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, dir)` - transform the parsed package.json contents before looking at the "main" field
* pkg - package data
* dir - directory for package.json (Note: the second argument will change to "pkgfile" in v2)
* `opts.pathFilter(pkg, path, relativePath)` - transform a path within a package
* pkg - package data
* path - the path being resolved
* relativePath - the path relative from the package.json location
* returns - a relative path that will be joined from the package.json location
* opts.paths - require.paths array to use if nothing is found on the normal `node_modules` recursive walk (probably don't use this)
For advanced users, `paths` can also be a `opts.paths(request, start, opts)` function
* request - the import specifier being resolved
* start - lookup path
* getNodeModulesDirs - a thunk (no-argument function) that returns the paths using standard `node_modules` resolution
* opts - the resolution options
* `opts.packageIterator(request, start, opts)` - return the list of candidate paths where the packages sources may be found (probably don't use this)
* request - the import specifier being resolved
* start - lookup path
* getPackageCandidates - a thunk (no-argument function) that returns the paths using standard `node_modules` resolution
* opts - the resolution options
* opts.moduleDirectory - directory (or directories) in which to recursively look for modules. default: `"node_modules"`
@@ -128,30 +218,59 @@ This is the way Node resolves dependencies when executed with the [--preserve-sy
default `opts` values:
``` javascript
```js
{
paths: [],
basedir: __dirname,
extensions: [ '.js' ],
extensions: ['.js'],
includeCoreModules: true,
readFileSync: fs.readFileSync,
isFile: function (file) {
try { return fs.statSync(file).isFile() }
catch (e) { return false }
isFile: function isFile(file) {
try {
var stat = fs.statSync(file);
} catch (e) {
if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false;
throw e;
}
return stat.isFile() || stat.isFIFO();
},
isDirectory: function isDirectory(dir) {
try {
var stat = fs.statSync(dir);
} catch (e) {
if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false;
throw e;
}
return stat.isDirectory();
},
realpathSync: function realpathSync(file) {
try {
var realpath = typeof fs.realpathSync.native === 'function' ? fs.realpathSync.native : fs.realpathSync;
return realpath(file);
} catch (realPathErr) {
if (realPathErr.code !== 'ENOENT') {
throw realPathErr;
}
}
return file;
},
readPackageSync: function defaultReadPackageSync(readFileSync, pkgfile) {
var body = readFileSync(pkgfile);
try {
var pkg = JSON.parse(body);
return pkg;
} catch (jsonErr) {}
},
moduleDirectory: 'node_modules',
preserveSymlinks: true
}
````
## resolve.isCore(pkg)
Return whether a package is in core.
```
# install
With [npm](https://npmjs.org) do:
```
```sh
npm install resolve
```
+50 -5
View File
@@ -10,6 +10,9 @@ test('core modules', function (t) {
st.ok(!resolve.isCore('seq'));
st.ok(!resolve.isCore('../'));
st.ok(!resolve.isCore('toString'));
st.end();
});
@@ -19,18 +22,60 @@ test('core modules', function (t) {
for (var i = 0; i < cores.length; ++i) {
var mod = cores[i];
var requireFunc = function () { require(mod); }; // eslint-disable-line no-loop-func
console.log(mod, resolve.core, resolve.core[mod]);
if (resolve.core[mod]) {
st.doesNotThrow(
function () { require(mod); }, // eslint-disable-line no-loop-func
'requiring ' + mod + ' does not throw'
);
st.doesNotThrow(requireFunc, mod + ' supported; requiring does not throw');
} else {
st.skip(mod + ' not supported');
st.throws(requireFunc, mod + ' not supported; requiring throws');
}
}
st.end();
});
t.test('core via repl module', { skip: !resolve.core.repl }, function (st) {
var libs = require('repl')._builtinLibs; // eslint-disable-line no-underscore-dangle
if (!libs) {
st.skip('module.builtinModules does not exist');
return st.end();
}
for (var i = 0; i < libs.length; ++i) {
var mod = libs[i];
st.ok(resolve.core[mod], mod + ' is a core module');
st.doesNotThrow(
function () { require(mod); }, // eslint-disable-line no-loop-func
'requiring ' + mod + ' does not throw'
);
}
st.end();
});
t.test('core via builtinModules list', { skip: !resolve.core.module }, function (st) {
var libs = require('module').builtinModules;
if (!libs) {
st.skip('module.builtinModules does not exist');
return st.end();
}
var blacklist = [
'_debug_agent',
'v8/tools/tickprocessor-driver',
'v8/tools/SourceMap',
'v8/tools/tickprocessor',
'v8/tools/profile'
];
for (var i = 0; i < libs.length; ++i) {
var mod = libs[i];
if (blacklist.indexOf(mod) === -1) {
st.ok(resolve.core[mod], mod + ' is a core module');
st.doesNotThrow(
function () { require(mod); }, // eslint-disable-line no-loop-func
'requiring ' + mod + ' does not throw'
);
}
}
st.end();
});
t.end();
});
+18 -2
View File
@@ -1,4 +1,5 @@
var test = require('tape');
var path = require('path');
var resolve = require('../');
test('faulty basedir must produce error in windows', { skip: process.platform !== 'win32' }, function (t) {
@@ -7,7 +8,22 @@ test('faulty basedir must produce error in windows', { skip: process.platform !=
var resolverDir = 'C:\\a\\b\\c\\d';
resolve('tape/lib/test.js', { basedir: resolverDir }, function (err, res, pkg) {
t.equal(true, !!err);
t.equal(!!err, true);
});
});
test('non-existent basedir should not throw when preserveSymlinks is false', function (t) {
t.plan(2);
var opts = {
basedir: path.join(path.sep, 'unreal', 'path', 'that', 'does', 'not', 'exist'),
preserveSymlinks: false
};
var module = './dotdot/abc';
resolve(module, opts, function (err, res) {
t.equal(err.code, 'MODULE_NOT_FOUND');
t.equal(res, undefined);
});
});
+20 -5
View File
@@ -3,17 +3,32 @@ var test = require('tape');
var resolve = require('../');
test('filter', function (t) {
t.plan(2);
t.plan(4);
var dir = path.join(__dirname, 'resolver');
var packageFilterArgs;
resolve('./baz', {
basedir: dir,
packageFilter: function (pkg) {
pkg.main = 'doom';
packageFilter: function (pkg, pkgfile) {
pkg.main = 'doom'; // eslint-disable-line no-param-reassign
packageFilterArgs = [pkg, pkgfile];
return pkg;
}
}, function (err, res, pkg) {
if (err) t.fail(err);
t.equal(res, path.join(dir, 'baz/doom.js'));
t.equal(pkg.main, 'doom');
t.equal(res, path.join(dir, 'baz/doom.js'), 'changing the package "main" works');
var packageData = packageFilterArgs[0];
t.equal(pkg, packageData, 'first packageFilter argument is "pkg"');
t.equal(packageData.main, 'doom', 'package "main" was altered');
var packageFile = packageFilterArgs[1];
t.equal(
packageFile,
path.join(dir, 'baz/package.json'),
'second packageFilter argument is "pkgfile"'
);
t.end();
});
});
+20 -3
View File
@@ -4,13 +4,30 @@ var resolve = require('../');
test('filter', function (t) {
var dir = path.join(__dirname, 'resolver');
var packageFilterArgs;
var res = resolve.sync('./baz', {
basedir: dir,
packageFilter: function (pkg) {
pkg.main = 'doom';
// NOTE: in v2.x, this will be `pkg, pkgfile, dir`, but must remain "broken" here in v1.x for compatibility
packageFilter: function (pkg, /*pkgfile,*/ dir) { // eslint-disable-line spaced-comment
pkg.main = 'doom'; // eslint-disable-line no-param-reassign
packageFilterArgs = 'is 1.x' ? [pkg, dir] : [pkg, pkgfile, dir]; // eslint-disable-line no-constant-condition, no-undef
return pkg;
}
});
t.equal(res, path.join(dir, 'baz/doom.js'));
t.equal(res, path.join(dir, 'baz/doom.js'), 'changing the package "main" works');
var packageData = packageFilterArgs[0];
t.equal(packageData.main, 'doom', 'package "main" was altered');
if (!'is 1.x') { // eslint-disable-line no-constant-condition
var packageFile = packageFilterArgs[1];
t.equal(packageFile, path.join(dir, 'baz', 'package.json'), 'package.json path is correct');
}
var packageDir = packageFilterArgs['is 1.x' ? 1 : 2]; // eslint-disable-line no-constant-condition
// eslint-disable-next-line no-constant-condition
t.equal(packageDir, path.join(dir, 'baz'), ('is 1.x' ? 'second' : 'third') + ' packageFilter argument is "dir"');
t.end();
});
+172
View File
@@ -8,14 +8,23 @@ test('mock', function (t) {
var files = {};
files[path.resolve('/foo/bar/baz.js')] = 'beep';
var dirs = {};
dirs[path.resolve('/foo/bar')] = 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)]);
},
readFile: function (file, cb) {
cb(null, files[path.resolve(file)]);
},
realpath: function (file, cb) {
cb(null, file);
}
};
}
@@ -49,15 +58,24 @@ test('mock from package', function (t) {
var files = {};
files[path.resolve('/foo/bar/baz.js')] = 'beep';
var dirs = {};
dirs[path.resolve('/foo/bar')] = true;
function opts(basedir) {
return {
basedir: path.resolve(basedir),
isFile: function (file, cb) {
cb(null, Object.prototype.hasOwnProperty.call(files, file));
},
isDirectory: function (dir, cb) {
cb(null, !!dirs[path.resolve(dir)]);
},
'package': { main: 'bar' },
readFile: function (file, cb) {
cb(null, files[file]);
},
realpath: function (file, cb) {
cb(null, file);
}
};
}
@@ -94,14 +112,24 @@ test('mock package', function (t) {
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)]);
},
readFile: function (file, cb) {
cb(null, files[path.resolve(file)]);
},
realpath: function (file, cb) {
cb(null, file);
}
};
}
@@ -122,15 +150,25 @@ test('mock package from package', function (t) {
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);
}
};
}
@@ -141,3 +179,137 @@ test('mock package from package', function (t) {
t.equal(pkg && pkg.main, './baz.js');
});
});
test('symlinked', function (t) {
t.plan(4);
var files = {};
files[path.resolve('/foo/bar/baz.js')] = 'beep';
files[path.resolve('/foo/bar/symlinked/baz.js')] = 'beep';
var dirs = {};
dirs[path.resolve('/foo/bar')] = true;
dirs[path.resolve('/foo/bar/symlinked')] = true;
function opts(basedir) {
return {
preserveSymlinks: false,
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)]);
},
readFile: function (file, cb) {
cb(null, files[path.resolve(file)]);
},
realpath: function (file, cb) {
var resolved = path.resolve(file);
if (resolved.indexOf('symlinked') >= 0) {
cb(null, resolved);
return;
}
var ext = path.extname(resolved);
if (ext) {
var dir = path.dirname(resolved);
var base = path.basename(resolved);
cb(null, path.join(dir, 'symlinked', base));
} else {
cb(null, path.join(resolved, 'symlinked'));
}
}
};
}
resolve('./baz', opts('/foo/bar'), function (err, res, pkg) {
if (err) return t.fail(err);
t.equal(res, path.resolve('/foo/bar/symlinked/baz.js'));
t.equal(pkg, undefined);
});
resolve('./baz.js', opts('/foo/bar'), function (err, res, pkg) {
if (err) return t.fail(err);
t.equal(res, path.resolve('/foo/bar/symlinked/baz.js'));
t.equal(pkg, undefined);
});
});
test('readPackage', function (t) {
t.plan(3);
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'
});
files[path.resolve('/foo/node_modules/bar/baz.js')] = 'boop';
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);
}
};
}
t.test('with readFile', function (st) {
st.plan(3);
resolve('bar', opts('/foo'), function (err, res, pkg) {
st.error(err);
st.equal(res, path.resolve('/foo/node_modules/bar/baz.js'));
st.equal(pkg && pkg.main, './baz.js');
});
});
var readPackage = function (readFile, file, cb) {
var barPackage = path.join('bar', 'package.json');
if (file.slice(-barPackage.length) === barPackage) {
cb(null, { main: './something-else.js' });
} else {
cb(null, JSON.parse(files[path.resolve(file)]));
}
};
t.test('with readPackage', function (st) {
st.plan(3);
var options = opts('/foo');
delete options.readFile;
options.readPackage = readPackage;
resolve('bar', options, function (err, res, pkg) {
st.error(err);
st.equal(res, path.resolve('/foo/node_modules/bar/something-else.js'));
st.equal(pkg && pkg.main, './something-else.js');
});
});
t.test('with readFile and readPackage', function (st) {
st.plan(1);
var options = opts('/foo');
options.readPackage = readPackage;
resolve('bar', options, function (err) {
st.throws(function () { throw err; }, TypeError, 'errors when both readFile and readPackage are provided');
});
});
});
+153 -4
View File
@@ -8,14 +8,23 @@ test('mock', function (t) {
var files = {};
files[path.resolve('/foo/bar/baz.js')] = 'beep';
var dirs = {};
dirs[path.resolve('/foo/bar')] = true;
function opts(basedir) {
return {
basedir: path.resolve(basedir),
isFile: function (file) {
return Object.prototype.hasOwnProperty.call(files, file);
return Object.prototype.hasOwnProperty.call(files, path.resolve(file));
},
isDirectory: function (dir) {
return !!dirs[path.resolve(dir)];
},
readFileSync: function (file) {
return files[file];
return files[path.resolve(file)];
},
realpathSync: function (file) {
return file;
}
};
}
@@ -48,14 +57,24 @@ test('mock package', function (t) {
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, file);
return Object.prototype.hasOwnProperty.call(files, path.resolve(file));
},
isDirectory: function (dir) {
return !!dirs[path.resolve(dir)];
},
readFileSync: function (file) {
return files[file];
return files[path.resolve(file)];
},
realpathSync: function (file) {
return file;
}
};
}
@@ -65,3 +84,133 @@ test('mock package', function (t) {
path.resolve('/foo/node_modules/bar/baz.js')
);
});
test('symlinked', function (t) {
t.plan(2);
var files = {};
files[path.resolve('/foo/bar/baz.js')] = 'beep';
files[path.resolve('/foo/bar/symlinked/baz.js')] = 'beep';
var dirs = {};
dirs[path.resolve('/foo/bar')] = true;
dirs[path.resolve('/foo/bar/symlinked')] = true;
function opts(basedir) {
return {
preserveSymlinks: false,
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) {
var resolved = path.resolve(file);
if (resolved.indexOf('symlinked') >= 0) {
return resolved;
}
var ext = path.extname(resolved);
if (ext) {
var dir = path.dirname(resolved);
var base = path.basename(resolved);
return path.join(dir, 'symlinked', base);
} else {
return path.join(resolved, 'symlinked');
}
}
};
}
t.equal(
resolve.sync('./baz', opts('/foo/bar')),
path.resolve('/foo/bar/symlinked/baz.js')
);
t.equal(
resolve.sync('./baz.js', opts('/foo/bar')),
path.resolve('/foo/bar/symlinked/baz.js')
);
});
test('readPackageSync', function (t) {
t.plan(3);
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'
});
files[path.resolve('/foo/node_modules/bar/baz.js')] = 'boop';
var dirs = {};
dirs[path.resolve('/foo')] = true;
dirs[path.resolve('/foo/node_modules')] = true;
function opts(basedir, useReadPackage) {
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: useReadPackage ? null : function (file) {
return files[path.resolve(file)];
},
realpathSync: function (file) {
return file;
}
};
}
t.test('with readFile', function (st) {
st.plan(1);
st.equal(
resolve.sync('bar', opts('/foo')),
path.resolve('/foo/node_modules/bar/baz.js')
);
});
var readPackageSync = 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.test('with readPackage', function (st) {
st.plan(1);
var options = opts('/foo');
delete options.readFileSync;
options.readPackageSync = readPackageSync;
st.equal(
resolve.sync('bar', options),
path.resolve('/foo/node_modules/bar/something-else.js')
);
});
t.test('with readFile and readPackage', function (st) {
st.plan(1);
var options = opts('/foo');
options.readPackageSync = readPackageSync;
st.throws(
function () { resolve.sync('bar', options); },
TypeError,
'errors when both readFile and readPackage are provided'
);
});
});
+52 -2
View File
@@ -7,6 +7,11 @@ var nodeModulesPaths = require('../lib/node-modules-paths');
var verifyDirs = function verifyDirs(t, start, dirs, moduleDirectories, paths) {
var moduleDirs = [].concat(moduleDirectories || 'node_modules');
if (paths) {
for (var k = 0; k < paths.length; ++k) {
moduleDirs.push(path.basename(paths[k]));
}
}
var foundModuleDirs = {};
var uniqueDirs = {};
@@ -20,7 +25,7 @@ var verifyDirs = function verifyDirs(t, start, dirs, moduleDirectories, paths) {
}
t.equal(keys(parsedDirs).length >= start.split(path.sep).length, true, 'there are >= dirs than "start" has');
var foundModuleDirNames = keys(foundModuleDirs);
t.deepEqual(foundModuleDirNames, moduleDirs.concat(paths || []), 'all desired module dirs were found');
t.deepEqual(foundModuleDirNames, moduleDirs, 'all desired module dirs were found');
t.equal(keys(uniqueDirs).length, dirs.length, 'all dirs provided were unique');
var counts = {};
@@ -49,7 +54,7 @@ test('node-modules-paths', function (t) {
t.end();
});
t.test('with paths option', function (t) {
t.test('with paths=array option', function (t) {
var start = path.join(__dirname, 'resolver');
var paths = ['a', 'b'];
var dirs = nodeModulesPaths(start, { paths: paths });
@@ -59,6 +64,29 @@ test('node-modules-paths', function (t) {
t.end();
});
t.test('with paths=function option', function (t) {
var paths = function paths(request, absoluteStart, getNodeModulesDirs, opts) {
return getNodeModulesDirs().concat(path.join(absoluteStart, 'not node modules', request));
};
var start = path.join(__dirname, 'resolver');
var dirs = nodeModulesPaths(start, { paths: paths }, 'pkg');
verifyDirs(t, start, dirs, null, [path.join(start, 'not node modules', 'pkg')]);
t.end();
});
t.test('with paths=function skipping node modules resolution', function (t) {
var paths = function paths(request, absoluteStart, getNodeModulesDirs, opts) {
return [];
};
var start = path.join(__dirname, 'resolver');
var dirs = nodeModulesPaths(start, { paths: paths });
t.deepEqual(dirs, [], 'no node_modules was computed');
t.end();
});
t.test('with moduleDirectory option', function (t) {
var start = path.join(__dirname, 'resolver');
var moduleDirectory = 'not node modules';
@@ -90,4 +118,26 @@ test('node-modules-paths', function (t) {
t.end();
});
t.test('combine paths correctly on Windows', function (t) {
var start = 'C:\\Users\\username\\myProject\\src';
var paths = [];
var moduleDirectories = ['node_modules', start];
var dirs = nodeModulesPaths(start, { paths: paths, moduleDirectory: moduleDirectories });
t.equal(dirs.indexOf(path.resolve(start)) > -1, true, 'should contain start dir');
t.end();
});
t.test('combine paths correctly on non-Windows', { skip: process.platform === 'win32' }, function (t) {
var start = '/Users/username/git/myProject/src';
var paths = [];
var moduleDirectories = ['node_modules', '/Users/username/git/myProject/src'];
var dirs = nodeModulesPaths(start, { paths: paths, moduleDirectory: moduleDirectories });
t.equal(dirs.indexOf(path.resolve(start)) > -1, true, 'should contain start dir');
t.end();
});
});
+32 -11
View File
@@ -1,18 +1,34 @@
var fs = require('fs');
var path = require('path');
var test = require('tape');
var resolve = require('../');
test('$NODE_PATH', function (t) {
t.plan(4);
t.plan(8);
var isDir = function (dir, cb) {
if (dir === '/node_path' || dir === 'node_path/x') {
return cb(null, true);
}
fs.stat(dir, function (err, stat) {
if (!err) {
return cb(null, stat.isDirectory());
}
if (err.code === 'ENOENT' || err.code === 'ENOTDIR') return cb(null, false);
return cb(err);
});
};
resolve('aaa', {
paths: [
path.join(__dirname, '/node_path/x'),
path.join(__dirname, '/node_path/y')
],
basedir: __dirname
basedir: __dirname,
isDirectory: isDir
}, function (err, res) {
t.equal(res, path.join(__dirname, '/node_path/x/aaa/index.js'));
t.error(err);
t.equal(res, path.join(__dirname, '/node_path/x/aaa/index.js'), 'aaa resolves');
});
resolve('bbb', {
@@ -20,9 +36,11 @@ test('$NODE_PATH', function (t) {
path.join(__dirname, '/node_path/x'),
path.join(__dirname, '/node_path/y')
],
basedir: __dirname
basedir: __dirname,
isDirectory: isDir
}, function (err, res) {
t.equal(res, path.join(__dirname, '/node_path/y/bbb/index.js'));
t.error(err);
t.equal(res, path.join(__dirname, '/node_path/y/bbb/index.js'), 'bbb resolves');
});
resolve('ccc', {
@@ -30,20 +48,23 @@ test('$NODE_PATH', function (t) {
path.join(__dirname, '/node_path/x'),
path.join(__dirname, '/node_path/y')
],
basedir: __dirname
basedir: __dirname,
isDirectory: isDir
}, function (err, res) {
t.equal(res, path.join(__dirname, '/node_path/x/ccc/index.js'));
t.error(err);
t.equal(res, path.join(__dirname, '/node_path/x/ccc/index.js'), 'ccc resolves');
});
// ensure that relative paths still resolve against the
// regular `node_modules` correctly
// ensure that relative paths still resolve against the regular `node_modules` correctly
resolve('tap', {
paths: [
'node_path'
],
basedir: 'node_path/x'
basedir: path.join(__dirname, 'node_path/x'),
isDirectory: isDir
}, function (err, res) {
var root = require('tap/package.json').main;
t.equal(res, path.resolve(__dirname, '..', 'node_modules/tap', root));
t.error(err);
t.equal(res, path.resolve(__dirname, '..', 'node_modules/tap', root), 'tap resolves');
});
});
+59 -26
View File
@@ -2,41 +2,74 @@ var path = require('path');
var test = require('tape');
var resolve = require('../');
test('#62: deep module references and the pathFilter', function (t) {
t.plan(9);
var resolverDir = path.join(__dirname, '/pathfilter/deep_ref');
var resolverDir = path.join(__dirname, '/pathfilter/deep_ref');
var pathFilter = function (pkg, x, remainder) {
var pathFilterFactory = function (t) {
return function (pkg, x, remainder) {
t.equal(pkg.version, '1.2.3');
t.equal(x, path.join(resolverDir, 'node_modules/deep/ref'));
t.equal(remainder, 'ref');
return 'alt';
};
};
resolve('deep/ref', { basedir: resolverDir }, function (err, res, pkg) {
if (err) t.fail(err);
test('#62: deep module references and the pathFilter', function (t) {
t.test('deep/ref.js', function (st) {
st.plan(3);
t.equal(pkg.version, '1.2.3');
t.equal(res, path.join(resolverDir, 'node_modules/deep/ref.js'));
resolve('deep/ref', { basedir: resolverDir }, function (err, res, pkg) {
if (err) st.fail(err);
st.equal(pkg.version, '1.2.3');
st.equal(res, path.join(resolverDir, 'node_modules/deep/ref.js'));
});
var res = resolve.sync('deep/ref', { basedir: resolverDir });
st.equal(res, path.join(resolverDir, 'node_modules/deep/ref.js'));
});
resolve(
'deep/deeper/ref',
{ basedir: resolverDir },
function (err, res, pkg) {
if (err) t.fail(err);
t.notEqual(pkg, undefined);
t.equal(pkg.version, '1.2.3');
t.equal(res, path.join(resolverDir, 'node_modules/deep/deeper/ref.js'));
}
);
t.test('deep/deeper/ref', function (st) {
st.plan(4);
resolve(
'deep/ref',
{ basedir: resolverDir, pathFilter: pathFilter },
function (err, res, pkg) {
if (err) t.fail(err);
t.equal(res, path.join(resolverDir, 'node_modules/deep/alt.js'));
}
);
resolve(
'deep/deeper/ref',
{ basedir: resolverDir },
function (err, res, pkg) {
if (err) t.fail(err);
st.notEqual(pkg, undefined);
st.equal(pkg.version, '1.2.3');
st.equal(res, path.join(resolverDir, 'node_modules/deep/deeper/ref.js'));
}
);
var res = resolve.sync(
'deep/deeper/ref',
{ basedir: resolverDir }
);
st.equal(res, path.join(resolverDir, 'node_modules/deep/deeper/ref.js'));
});
t.test('deep/ref alt', function (st) {
st.plan(8);
var pathFilter = pathFilterFactory(st);
var res = resolve.sync(
'deep/ref',
{ basedir: resolverDir, pathFilter: pathFilter }
);
st.equal(res, path.join(resolverDir, 'node_modules/deep/alt.js'));
resolve(
'deep/ref',
{ basedir: resolverDir, pathFilter: pathFilter },
function (err, res, pkg) {
if (err) st.fail(err);
st.equal(res, path.join(resolverDir, 'node_modules/deep/alt.js'));
st.end();
}
);
});
t.end();
});
+118 -17
View File
@@ -3,7 +3,7 @@ var test = require('tape');
var resolve = require('../');
test('async foo', function (t) {
t.plan(10);
t.plan(12);
var dir = path.join(__dirname, 'resolver');
resolve('./foo', { basedir: dir }, function (err, res, pkg) {
@@ -30,10 +30,20 @@ test('async foo', function (t) {
t.equal(pkg.main, 'resolver');
});
resolve('./foo', { basedir: dir, filename: path.join(dir, 'baz.js') }, function (err, res) {
if (err) t.fail(err);
t.equal(res, path.join(dir, 'foo.js'));
});
resolve('foo', { basedir: dir }, function (err) {
t.equal(err.message, "Cannot find module 'foo' from '" + path.resolve(dir) + "'");
t.equal(err.code, 'MODULE_NOT_FOUND');
});
// Test that filename is reported as the "from" value when passed.
resolve('foo', { basedir: dir, filename: path.join(dir, 'baz.js') }, function (err) {
t.equal(err.message, "Cannot find module 'foo' from '" + path.join(dir, 'baz.js') + "'");
});
});
test('bar', function (t) {
@@ -55,7 +65,7 @@ test('bar', function (t) {
resolve('foo', { basedir: dir + '/bar', 'package': { main: 'bar' } }, function (err, res, pkg) {
if (err) t.fail(err);
t.equal(res, path.join(dir, 'bar/node_modules/foo/index.js'));
t.equal(pkg, undefined);
t.equal(pkg.main, 'bar');
});
});
@@ -113,7 +123,7 @@ test('biz', function (t) {
resolve('tiv', { basedir: dir + '/grux', 'package': { main: 'grux' } }, function (err, res, pkg) {
if (err) t.fail(err);
t.equal(res, path.join(dir, 'tiv/index.js'));
t.equal(pkg, undefined);
t.equal(pkg.main, 'grux');
});
resolve('tiv', { basedir: dir + '/garply' }, function (err, res, pkg) {
@@ -125,7 +135,7 @@ test('biz', function (t) {
resolve('tiv', { basedir: dir + '/garply', 'package': { main: './lib' } }, function (err, res, pkg) {
if (err) t.fail(err);
t.equal(res, path.join(dir, 'tiv/index.js'));
t.equal(pkg, undefined);
t.equal(pkg.main, './lib');
});
resolve('grux', { basedir: dir + '/tiv' }, function (err, res, pkg) {
@@ -137,7 +147,7 @@ test('biz', function (t) {
resolve('grux', { basedir: dir + '/tiv', 'package': { main: 'tiv' } }, function (err, res, pkg) {
if (err) t.fail(err);
t.equal(res, path.join(dir, 'grux/index.js'));
t.equal(pkg, undefined);
t.equal(pkg.main, 'tiv');
});
resolve('garply', { basedir: dir + '/tiv' }, function (err, res, pkg) {
@@ -176,7 +186,7 @@ test('normalize', function (t) {
});
test('cup', function (t) {
t.plan(4);
t.plan(5);
var dir = path.join(__dirname, 'resolver');
resolve('./cup', { basedir: dir, extensions: ['.js', '.coffee'] }, function (err, res) {
@@ -193,6 +203,11 @@ test('cup', function (t) {
t.equal(err.message, "Cannot find module './cup' from '" + path.resolve(dir) + "'");
t.equal(err.code, 'MODULE_NOT_FOUND');
});
// Test that filename is reported as the "from" value when passed.
resolve('./cup', { basedir: dir, extensions: ['.js'], filename: path.join(dir, 'cupboard.js') }, function (err, res) {
t.equal(err.message, "Cannot find module './cup' from '" + path.join(dir, 'cupboard.js') + "'");
});
});
test('mug', function (t) {
@@ -241,6 +256,22 @@ test('other path', function (t) {
});
});
test('path iterator', function (t) {
t.plan(2);
var resolverDir = path.join(__dirname, 'resolver');
var exactIterator = function (x, start, getPackageCandidates, opts) {
return [path.join(resolverDir, x)];
};
resolve('baz', { packageIterator: exactIterator }, function (err, res, pkg) {
if (err) t.fail(err);
t.equal(res, path.join(resolverDir, 'baz/quux.js'));
t.equal(pkg && pkg.name, 'baz');
});
});
test('incorrect main', function (t) {
t.plan(1);
@@ -268,17 +299,6 @@ test('without basedir', function (t) {
});
});
test('#25: node modules with the same name as node stdlib modules', function (t) {
t.plan(1);
var resolverDir = path.join(__dirname, 'resolver/punycode');
resolve('punycode', { basedir: resolverDir }, function (err, res, pkg) {
if (err) t.fail(err);
t.equal(res, path.join(resolverDir, 'node_modules/punycode/index.js'));
});
});
test('#52 - incorrectly resolves module-paths like "./someFolder/" when there is a file of the same name', function (t) {
t.plan(2);
@@ -295,6 +315,22 @@ test('#52 - incorrectly resolves module-paths like "./someFolder/" when there is
});
});
test('#211 - incorrectly resolves module-paths like "." when from inside a folder with a sibling file of the same name', function (t) {
t.plan(2);
var dir = path.join(__dirname, 'resolver');
resolve('./', { basedir: path.join(dir, 'same_names/foo') }, function (err, res, pkg) {
if (err) t.fail(err);
t.equal(res, path.join(dir, 'same_names/foo/index.js'));
});
resolve('.', { basedir: path.join(dir, 'same_names/foo') }, function (err, res, pkg) {
if (err) t.fail(err);
t.equal(res, path.join(dir, 'same_names/foo/index.js'));
});
});
test('async: #121 - treating an existing file as a dir when no basedir', function (t) {
var testFile = path.basename(__filename);
@@ -347,3 +383,68 @@ test('async dot slash main', function (t) {
t.end();
});
});
test('not a directory', function (t) {
t.plan(6);
var path = './foo';
resolve(path, { basedir: __filename }, function (err, res, pkg) {
t.ok(err, 'a non-directory errors');
t.equal(arguments.length, 1);
t.equal(res, undefined);
t.equal(pkg, undefined);
t.equal(err && err.message, 'Cannot find module \'' + path + '\' from \'' + __filename + '\'');
t.equal(err && err.code, 'MODULE_NOT_FOUND');
});
});
test('non-string "main" field in package.json', function (t) {
t.plan(5);
var dir = path.join(__dirname, 'resolver');
resolve('./invalid_main', { basedir: dir }, function (err, res, pkg) {
t.ok(err, 'errors on non-string main');
t.equal(err.message, 'package “invalid main” `main` must be a string');
t.equal(err.code, 'INVALID_PACKAGE_MAIN');
t.equal(res, undefined, 'res is undefined');
t.equal(pkg, undefined, 'pkg is undefined');
});
});
test('non-string "main" field in package.json', function (t) {
t.plan(5);
var dir = path.join(__dirname, 'resolver');
resolve('./invalid_main', { basedir: dir }, function (err, res, pkg) {
t.ok(err, 'errors on non-string main');
t.equal(err.message, 'package “invalid main” `main` must be a string');
t.equal(err.code, 'INVALID_PACKAGE_MAIN');
t.equal(res, undefined, 'res is undefined');
t.equal(pkg, undefined, 'pkg is undefined');
});
});
test('browser field in package.json', function (t) {
t.plan(3);
var dir = path.join(__dirname, 'resolver');
resolve(
'./browser_field',
{
basedir: dir,
packageFilter: function packageFilter(pkg) {
if (pkg.browser) {
pkg.main = pkg.browser; // eslint-disable-line no-param-reassign
delete pkg.browser; // eslint-disable-line no-param-reassign
}
return pkg;
}
},
function (err, res, pkg) {
if (err) t.fail(err);
t.equal(res, path.join(dir, 'browser_field', 'b.js'));
t.equal(pkg && pkg.main, 'b');
t.equal(pkg && pkg.browser, undefined);
}
);
});
+1
View File
@@ -1,3 +1,4 @@
{
"name": "baz",
"main": "quux.js"
}
+102 -11
View File
@@ -15,10 +15,26 @@ test('foo', function (t) {
path.join(dir, 'foo.js')
);
t.equal(
resolve.sync('./foo.js', { basedir: dir, filename: path.join(dir, 'bar.js') }),
path.join(dir, 'foo.js')
);
t.throws(function () {
resolve.sync('foo', { basedir: dir });
});
// Test that filename is reported as the "from" value when passed.
t.throws(
function () {
resolve.sync('foo', { basedir: dir, filename: path.join(dir, 'bar.js') });
},
{
name: 'Error',
message: "Cannot find module 'foo' from '" + path.join(dir, 'bar.js') + "'"
}
);
t.end();
});
@@ -156,6 +172,21 @@ test('other path', function (t) {
t.end();
});
test('path iterator', function (t) {
var resolverDir = path.join(__dirname, 'resolver');
var exactIterator = function (x, start, getPackageCandidates, opts) {
return [path.join(resolverDir, x)];
};
t.equal(
resolve.sync('baz', { packageIterator: exactIterator }),
path.join(resolverDir, 'baz/quux.js')
);
t.end();
});
test('incorrect main', function (t) {
var resolverDir = path.join(__dirname, 'resolver');
var dir = path.join(resolverDir, 'incorrect_main');
@@ -168,17 +199,6 @@ test('incorrect main', function (t) {
t.end();
});
test('#25: node modules with the same name as node stdlib modules', function (t) {
var resolverDir = path.join(__dirname, 'resolver/punycode');
t.equal(
resolve.sync('punycode', { basedir: resolverDir }),
path.join(resolverDir, 'node_modules/punycode/index.js')
);
t.end();
});
var stubStatSync = function stubStatSync(fn) {
var fs = require('fs');
var statSync = fs.statSync;
@@ -218,6 +238,20 @@ test('#52 - incorrectly resolves module-paths like "./someFolder/" when there is
t.end();
});
test('#211 - incorrectly resolves module-paths like "." when from inside a folder with a sibling file of the same name', function (t) {
var dir = path.join(__dirname, 'resolver');
t.equal(
resolve.sync('./', { basedir: path.join(dir, 'same_names/foo') }),
path.join(dir, 'same_names/foo/index.js')
);
t.equal(
resolve.sync('.', { basedir: path.join(dir, 'same_names/foo') }),
path.join(dir, 'same_names/foo/index.js')
);
t.end();
});
test('sync: #121 - treating an existing file as a dir when no basedir', function (t) {
var testFile = path.basename(__filename);
@@ -265,3 +299,60 @@ test('sync dot slash main', function (t) {
t.ok(new Date() - start < 50, 'resolve.sync timedout');
t.end();
});
test('not a directory', function (t) {
var path = './foo';
try {
resolve.sync(path, { basedir: __filename });
t.fail();
} catch (err) {
t.ok(err, 'a non-directory errors');
t.equal(err && err.message, 'Cannot find module \'' + path + "' from '" + __filename + "'");
t.equal(err && err.code, 'MODULE_NOT_FOUND');
}
t.end();
});
test('non-string "main" field in package.json', function (t) {
var dir = path.join(__dirname, 'resolver');
try {
var result = resolve.sync('./invalid_main', { basedir: dir });
t.equal(result, undefined, 'result should not exist');
t.fail('should not get here');
} catch (err) {
t.ok(err, 'errors on non-string main');
t.equal(err.message, 'package “invalid main” `main` must be a string');
t.equal(err.code, 'INVALID_PACKAGE_MAIN');
}
t.end();
});
test('non-string "main" field in package.json', function (t) {
var dir = path.join(__dirname, 'resolver');
try {
var result = resolve.sync('./invalid_main', { basedir: dir });
t.equal(result, undefined, 'result should not exist');
t.fail('should not get here');
} catch (err) {
t.ok(err, 'errors on non-string main');
t.equal(err.message, 'package “invalid main” `main` must be a string');
t.equal(err.code, 'INVALID_PACKAGE_MAIN');
}
t.end();
});
test('browser field in package.json', function (t) {
var dir = path.join(__dirname, 'resolver');
var res = resolve.sync('./browser_field', {
basedir: dir,
packageFilter: function packageFilter(pkg) {
if (pkg.browser) {
pkg.main = pkg.browser; // eslint-disable-line no-param-reassign
delete pkg.browser; // eslint-disable-line no-param-reassign
}
return pkg;
}
});
t.equal(res, path.join(dir, 'browser_field', 'b.js'));
t.end();
});
+125 -3
View File
@@ -1,24 +1,50 @@
var path = require('path');
var fs = require('fs');
var test = require('tape');
var map = require('array.prototype.map');
var resolve = require('../');
var symlinkDir = path.join(__dirname, 'resolver', 'symlinked', 'symlink');
var packageDir = path.join(__dirname, 'resolver', 'symlinked', '_', 'node_modules', 'package');
var modADir = path.join(__dirname, 'symlinks', 'source', 'node_modules', 'mod-a');
var symlinkModADir = path.join(__dirname, 'symlinks', 'dest', 'node_modules', 'mod-a');
try {
fs.unlinkSync(symlinkDir);
} catch (err) {}
try {
fs.unlinkSync(packageDir);
} catch (err) {}
try {
fs.unlinkSync(modADir);
} catch (err) {}
try {
fs.unlinkSync(symlinkModADir);
} catch (err) {}
try {
fs.symlinkSync('./_/symlink_target', symlinkDir, 'dir');
} catch (err) {
// if fails then it is probably on Windows and lets try to create a junction
fs.symlinkSync(path.join(__dirname, 'resolver', 'symlinked', '_', 'symlink_target') + '\\', symlinkDir, 'junction');
}
try {
fs.symlinkSync('../../package', packageDir, 'dir');
} catch (err) {
// if fails then it is probably on Windows and lets try to create a junction
fs.symlinkSync(path.join(__dirname, '..', '..', 'package') + '\\', packageDir, 'junction');
}
try {
fs.symlinkSync('../../source/node_modules/mod-a', symlinkModADir, 'dir');
} catch (err) {
// if fails then it is probably on Windows and lets try to create a junction
fs.symlinkSync(path.join(__dirname, '..', '..', 'source', 'node_modules', 'mod-a') + '\\', symlinkModADir, 'junction');
}
test('symlink', function (t) {
t.plan(1);
t.plan(2);
resolve('foo', { basedir: symlinkDir, preserveSymlinks: false }, function (err, res, pkg) {
if (err) t.fail(err);
t.error(err);
t.equal(res, path.join(__dirname, 'resolver', 'symlinked', '_', 'node_modules', 'foo.js'));
});
});
@@ -41,7 +67,12 @@ test('sync symlink when preserveSymlinks = true', function (t) {
test('sync symlink', function (t) {
var start = new Date();
t.equal(resolve.sync('foo', { basedir: symlinkDir, preserveSymlinks: false }), path.join(__dirname, 'resolver', 'symlinked', '_', 'node_modules', 'foo.js'));
t.doesNotThrow(function () {
t.equal(
resolve.sync('foo', { basedir: symlinkDir, preserveSymlinks: false }),
path.join(__dirname, 'resolver', 'symlinked', '_', 'node_modules', 'foo.js')
);
});
t.ok(new Date() - start < 50, 'resolve.sync timedout');
t.end();
});
@@ -52,3 +83,94 @@ test('sync symlink when preserveSymlinks = true', function (t) {
}, /Cannot find module 'foo'/);
t.end();
});
test('sync symlink from node_modules to other dir when preserveSymlinks = false', function (t) {
var basedir = path.join(__dirname, 'resolver', 'symlinked', '_');
var fn = resolve.sync('package', { basedir: basedir, preserveSymlinks: false });
t.equal(fn, path.resolve(__dirname, 'resolver/symlinked/package/bar.js'));
t.end();
});
test('async symlink from node_modules to other dir when preserveSymlinks = false', function (t) {
t.plan(2);
var basedir = path.join(__dirname, 'resolver', 'symlinked', '_');
resolve('package', { basedir: basedir, preserveSymlinks: false }, function (err, result) {
t.notOk(err, 'no error');
t.equal(result, path.resolve(__dirname, 'resolver/symlinked/package/bar.js'));
});
});
test('packageFilter', function (t) {
function relative(x) {
return path.relative(__dirname, x);
}
function testPackageFilter(preserveSymlinks) {
return function (st) {
st.plan('is 1.x' ? 3 : 5); // eslint-disable-line no-constant-condition
var destMain = 'symlinks/dest/node_modules/mod-a/index.js';
var destPkg = 'symlinks/dest/node_modules/mod-a/package.json';
var sourceMain = 'symlinks/source/node_modules/mod-a/index.js';
var sourcePkg = 'symlinks/source/node_modules/mod-a/package.json';
var destDir = path.join(__dirname, 'symlinks', 'dest');
/* eslint multiline-comment-style: 0 */
/* v2.x will restore these tests
var packageFilterPath = [];
var actualPath = resolve.sync('mod-a', {
basedir: destDir,
preserveSymlinks: preserveSymlinks,
packageFilter: function (pkg, pkgfile, dir) {
packageFilterPath.push(pkgfile);
}
});
st.equal(
relative(actualPath),
path.normalize(preserveSymlinks ? destMain : sourceMain),
'sync: actual path is correct'
);
st.deepEqual(
map(packageFilterPath, relative),
map(preserveSymlinks ? [destPkg, destPkg] : [sourcePkg, sourcePkg], path.normalize),
'sync: packageFilter pkgfile arg is correct'
);
*/
var asyncPackageFilterPath = [];
resolve(
'mod-a',
{
basedir: destDir,
preserveSymlinks: preserveSymlinks,
packageFilter: function (pkg, pkgfile) {
asyncPackageFilterPath.push(pkgfile);
}
},
function (err, actualPath) {
st.error(err, 'no error');
st.equal(
relative(actualPath),
path.normalize(preserveSymlinks ? destMain : sourceMain),
'async: actual path is correct'
);
st.deepEqual(
map(asyncPackageFilterPath, relative),
map(
preserveSymlinks ? [destPkg, destPkg, destPkg] : [sourcePkg, sourcePkg, sourcePkg],
path.normalize
),
'async: packageFilter pkgfile arg is correct'
);
}
);
};
}
t.test('preserveSymlinks: false', testPackageFilter(false));
t.test('preserveSymlinks: true', testPackageFilter(true));
t.end();
});