Merge pull request #113 from PradnyaBaviskar/lb-boot-issue-73-4

Resolve module paths as relative to appRootDir - for middleware
This commit is contained in:
Miroslav Bajtoš 2015-03-20 16:32:24 +01:00
commit d7c67c803a
2 changed files with 73 additions and 30 deletions

View File

@ -271,7 +271,7 @@ function findModelDefinitions(rootDir, sources) {
var registry = {}; var registry = {};
sources.forEach(function(src) { sources.forEach(function(src) {
var srcDir = resolveAppPath(rootDir, src); var srcDir = tryResolveAppPath(rootDir, src);
if (!srcDir) { if (!srcDir) {
debug('Skipping unknown module source dir %j', src); debug('Skipping unknown module source dir %j', src);
return; return;
@ -300,6 +300,16 @@ function findModelDefinitions(rootDir, sources) {
} }
function resolveAppPath(rootDir, relativePath) { function resolveAppPath(rootDir, relativePath) {
var resolvedPath = tryResolveAppPath(rootDir, relativePath);
if (resolvedPath === undefined) {
var err = new Error('Cannot resolve path "' + relativePath + '"');
err.code = 'PATH_NOT_FOUND';
throw err;
}
return resolvedPath;
}
function tryResolveAppPath(rootDir, relativePath) {
var fullPath = path.resolve(rootDir, relativePath); var fullPath = path.resolve(rootDir, relativePath);
if (fs.existsSync(fullPath)) if (fs.existsSync(fullPath))
return fullPath; return fullPath;
@ -434,6 +444,7 @@ function resolveMiddlewarePath(rootDir, middleware) {
var segments = middleware.split('#'); var segments = middleware.split('#');
var pathName = segments[0]; var pathName = segments[0];
var fragment = segments[1]; var fragment = segments[1];
var middlewarePath = pathName;
if (fragment) { if (fragment) {
resolved.fragment = fragment; resolved.fragment = fragment;
@ -445,7 +456,7 @@ function resolveMiddlewarePath(rootDir, middleware) {
} }
if (!fragment) { if (!fragment) {
resolved.sourceFile = require.resolve(pathName); resolved.sourceFile = resolveAppPath(rootDir, middlewarePath);
return resolved; return resolved;
} }
@ -455,7 +466,7 @@ function resolveMiddlewarePath(rootDir, middleware) {
// function // function
var m = require(pathName); var m = require(pathName);
if (typeof m[fragment] === 'function') { if (typeof m[fragment] === 'function') {
resolved.sourceFile = require.resolve(pathName); resolved.sourceFile = resolveAppPath(rootDir, middlewarePath);
return resolved; return resolved;
} }
@ -473,7 +484,7 @@ function resolveMiddlewarePath(rootDir, middleware) {
for (var ix in candidates) { for (var ix in candidates) {
try { try {
resolved.sourceFile = require.resolve(candidates[ix]); resolved.sourceFile = resolveAppPath(rootDir, candidates[ix]);
delete resolved.fragment; delete resolved.fragment;
return resolved; return resolved;
} }
@ -519,7 +530,7 @@ function buildComponentInstructions(rootDir, componentConfig) {
function resolveRelativePaths(relativePaths, appRootDir) { function resolveRelativePaths(relativePaths, appRootDir) {
relativePaths.forEach(function(relativePath, k) { relativePaths.forEach(function(relativePath, k) {
var resolvedPath = resolveAppPath(appRootDir, relativePath); var resolvedPath = tryResolveAppPath(appRootDir, relativePath);
if (resolvedPath !== undefined) { if (resolvedPath !== undefined) {
relativePaths[k] = resolvedPath; relativePaths[k] = resolvedPath;
} else { } else {

View File

@ -858,10 +858,11 @@ describe('compiler', function() {
}); });
it('resolves paths relatively to appRootDir', function() { it('resolves paths relatively to appRootDir', function() {
appdir.writeFileSync('my-middleware.js', '');
appdir.writeConfigFileSync('./middleware.json', { appdir.writeConfigFileSync('./middleware.json', {
routes: { routes: {
// resolves to ./middleware.json // resolves to ./my-middleware.js
'./middleware': { } './my-middleware': { }
} }
}); });
@ -870,7 +871,7 @@ describe('compiler', function() {
expect(instructions.middleware).to.eql({ expect(instructions.middleware).to.eql({
phases: ['routes'], phases: ['routes'],
middleware: [{ middleware: [{
sourceFile: path.resolve(appdir.PATH, 'middleware.json'), sourceFile: path.resolve(appdir.PATH, 'my-middleware.js'),
config: { phase: 'routes' } config: { phase: 'routes' }
}] }]
}); });
@ -959,10 +960,10 @@ describe('compiler', function() {
}); });
it('supports multiple instances of the same middleware', function() { it('supports multiple instances of the same middleware', function() {
appdir.writeFileSync('my-middleware.js', '');
appdir.writeConfigFileSync('middleware.json', { appdir.writeConfigFileSync('middleware.json', {
'final': { 'final': {
'./middleware': [ './my-middleware': [
{ {
params: 'first' params: 'first'
}, },
@ -978,14 +979,14 @@ describe('compiler', function() {
expect(instructions.middleware.middleware) expect(instructions.middleware.middleware)
.to.eql([ .to.eql([
{ {
sourceFile: path.resolve(appdir.PATH, 'middleware.json'), sourceFile: path.resolve(appdir.PATH, 'my-middleware.js'),
config: { config: {
phase: 'final', phase: 'final',
params: 'first' params: 'first'
} }
}, },
{ {
sourceFile: path.resolve(appdir.PATH, 'middleware.json'), sourceFile: path.resolve(appdir.PATH, 'my-middleware.js'),
config: { config: {
phase: 'final', phase: 'final',
params: 'second' params: 'second'
@ -1043,27 +1044,58 @@ describe('compiler', function() {
'errorHandler'); 'errorHandler');
}); });
// FIXME: [rfeng] The following test is disabled until it('resolves modules relative to appRootDir', function() {
// https://github.com/strongloop/loopback-boot/issues/73 is fixed var HANDLER_FILE = 'node_modules/handler/index.js';
it.skip('resolves modules relative to appRootDir', function() { appdir.writeFileSync(
var HANDLER_FILE = 'node_modules/handler/index.js'; HANDLER_FILE,
appdir.writeFileSync( 'module.exports = function(req, res, next) { next(); }');
HANDLER_FILE,
'module.exports = function(req, res, next) { next(); }');
appdir.writeConfigFileSync('middleware.json', { appdir.writeConfigFileSync('middleware.json', {
'initial': { 'initial': {
'handler': {} 'handler': {}
} }
});
var instructions = boot.compile(appdir.PATH);
expect(instructions.middleware.middleware[0]).have.property(
'sourceFile',
appdir.resolve(HANDLER_FILE));
}); });
var instructions = boot.compile(appdir.PATH);
expect(instructions.middleware.middleware[0]).have.property(
'sourceFile',
appdir.resolve(HANDLER_FILE));
});
it('prefers appRootDir over node_modules for middleware', function() {
var appJS = appdir.writeFileSync('./my-middleware.js', '');
appdir.writeFileSync('node_modules/my-middleware.js', '');
appdir.writeConfigFileSync('middleware.json', {
'routes': {
'./my-middleware': {}
}
});
var instructions = boot.compile(appdir.PATH);
expect(instructions.middleware.middleware).to.have.length(1);
expect(instructions.middleware.middleware[0]).have.property(
'sourceFile', appJS);
});
it('does not treat module relative path as `appRootDir` relative',
function() {
appdir.writeFileSync('./my-middleware.js', '');
var moduleJS = appdir.writeFileSync('node_modules/my-middleware.js', '');
appdir.writeConfigFileSync('middleware.json', {
'routes': {
'my-middleware': {}
}
});
var instructions = boot.compile(appdir.PATH);
expect(instructions.middleware.middleware).to.have.length(1);
expect(instructions.middleware.middleware[0]).have.property(
'sourceFile', moduleJS);
});
describe('config with relative paths in params', function() { describe('config with relative paths in params', function() {
var RELATIVE_PATH_PARAMS = [ var RELATIVE_PATH_PARAMS = [
'$!./here', '$!./here',