src/Router.js
function _resolve(routes, path, req, res) {
	return Q.fcall(function() {

		path = path || [];

		var obj = routes;
		
		// Resolve promises first
		if(IS.obj(obj) && IS.fun(obj.then)) {
			var p = obj.then(function(ret) {
				return _resolve(ret, path, req, res);
			});
			return p;
		}

		// Resolve functions first
		if(IS.fun(obj)) {
			var p2 = Q.when(obj(req, res)).then(function(ret) {
				return _resolve(ret, path, req, res);
			});
			return p2;
		}
		
		// If the resource is undefined, return flags.notFound (resulting to a HTTP error 404).
		if(obj === undefined) {
			return flags.notFound;
		}
		
		// If path is at the end, then return the current resource.
		if(path.length === 0) {
			return obj;
		}
		
		// Handle arrays
		if(IS.array(obj)) {
			var k = path[0],
			    n = parseInt(path.shift(), 10);
			if(k === "length") {
				return _resolve(obj.length, path.shift(), req, res);
			}
			if(k !== ""+n) {
				return Q.fcall(function() { throw new errors.HTTPError({'code':400, 'desc':'Bad Request'}); });
			}
			return _resolve(obj[n], path.shift(), req, res);
		}
		
		// Handle objects
		if(IS.obj(obj)) {
			var k2 = path[0];
			if(obj[k2] === undefined) {
				return flags.notFound;
			}
			if(!obj.hasOwnProperty(k2)) {
				return Q.fcall(function() { throw new errors.HTTPError({'code':403, 'desc':'Forbidden'}); });
			}
			return _resolve(obj[path.shift()], path, req, res);
		}
		
		// Returns notFound because we still have keys in the path but nowhere to go.
		return flags.notFound;
	});
}
function _resolve(routes, path, req, res) {
	return Q.fcall(function() {

		path = path || [];

		var obj = routes;
		
		// Resolve promises first
		if(IS.obj(obj) && IS.fun(obj.then)) {
			var p = obj.then(function(ret) {
				return _resolve(ret, path, req, res);
			});
			return p;
		}

		// Resolve functions first
		if(IS.fun(obj)) {
			var p2 = Q.when(obj(req, res)).then(function(ret) {
				return _resolve(ret, path, req, res);
			});
			return p2;
		}
		
		// If the resource is undefined, return flags.notFound (resulting to a HTTP error 404).
		if(obj === undefined) {
			return flags.notFound;
		}
		
		// If path is at the end, then return the current resource.
		if(path.length === 0) {
			return obj;
		}
		
		// Handle arrays
		if(IS.array(obj)) {
			var k = path[0],
			    n = parseInt(path.shift(), 10);
			if(k === "length") {
				return _resolve(obj.length, path.shift(), req, res);
			}
			if(k !== ""+n) {
				return Q.fcall(function() { throw new errors.HTTPError({'code':400, 'desc':'Bad Request'}); });
			}
			return _resolve(obj[n], path.shift(), req, res);
		}
		
		// Handle objects
		if(IS.obj(obj)) {
			var k2 = path[0];
			if(obj[k2] === undefined) {
				return flags.notFound;
			}
			if(!obj.hasOwnProperty(k2)) {
				return Q.fcall(function() { throw new errors.HTTPError({'code':403, 'desc':'Forbidden'}); });
			}
			return _resolve(obj[path.shift()], path, req, res);
		}
		
		// Returns notFound because we still have keys in the path but nowhere to go.
		return flags.notFound;
	});
}
function _resolve ( routes , path , req , res ) { return Q . fcall ( function ( ) { path = path || [ ] ; var obj = routes ; // Resolve promises first if ( IS . obj ( obj ) && IS . fun ( obj . then ) ) { var p = obj . then ( function ( ret ) { return _resolve ( ret , path , req , res ) ; } ) ; return p ; } // Resolve functions first if ( IS . fun ( obj ) ) { var p2 = Q . when ( obj ( req , res ) ) . then ( function ( ret ) { return _resolve ( ret , path , req , res ) ; } ) ; return p2 ; } // If the resource is undefined, return flags.notFound (resulting to a HTTP error 404). if ( obj === undefined ) { return flags . notFound ; } // If path is at the end, then return the current resource. if ( path . length === 0 ) { return obj ; } // Handle arrays if ( IS . array ( obj ) ) { var k = path [ 0 ] , n = parseInt ( path . shift ( ) , 10 ) ; if ( k === "length" ) { return _resolve ( obj . length , path . shift ( ) , req , res ) ; } if ( k !== "" + n ) { return Q . fcall ( function ( ) { throw new errors . HTTPError ( { 'code' : 400 , 'desc' : 'Bad Request' } ) ; } ) ; } return _resolve ( obj [ n ] , path . shift ( ) , req , res ) ; } // Handle objects if ( IS . obj ( obj ) ) { var k2 = path [ 0 ] ; if ( obj [ k2 ] === undefined ) { return flags . notFound ; } if ( ! obj . hasOwnProperty ( k2 ) ) { return Q . fcall ( function ( ) { throw new errors . HTTPError ( { 'code' : 403 , 'desc' : 'Forbidden' } ) ; } ) ; } return _resolve ( obj [ path . shift ( ) ] , path , req , res ) ; } // Returns notFound because we still have keys in the path but nowhere to go. return flags . notFound ; } ) ; }
Internal target resolver
@param routes Object prepresenting routes to resources.
@param path Path to the resource as an array of keys.
Internal target resolver