228 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			228 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/*
 | 
						|
	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
						|
	Author Tobias Koppers @sokra
 | 
						|
*/
 | 
						|
var Tapable = require("tapable");
 | 
						|
var createInnerCallback = require("./createInnerCallback");
 | 
						|
 | 
						|
function Resolver(fileSystem) {
 | 
						|
	Tapable.call(this);
 | 
						|
	this.fileSystem = fileSystem;
 | 
						|
}
 | 
						|
module.exports = Resolver;
 | 
						|
 | 
						|
Resolver.prototype = Object.create(Tapable.prototype);
 | 
						|
 | 
						|
Resolver.prototype.constructor = Resolver;
 | 
						|
 | 
						|
Resolver.prototype.resolveSync = function resolveSync(context, path, request) {
 | 
						|
	var err, result, sync = false;
 | 
						|
	this.resolve(context, path, request, function(e, r) {
 | 
						|
		err = e;
 | 
						|
		result = r;
 | 
						|
		sync = true;
 | 
						|
	});
 | 
						|
	if(!sync) throw new Error("Cannot 'resolveSync' because the fileSystem is not sync. Use 'resolve'!");
 | 
						|
	if(err) throw err;
 | 
						|
	return result;
 | 
						|
};
 | 
						|
 | 
						|
Resolver.prototype.resolve = function resolve(context, path, request, callback) {
 | 
						|
	if(arguments.length === 3) {
 | 
						|
		throw new Error("Signature changed: context parameter added");
 | 
						|
	}
 | 
						|
	var resolver = this;
 | 
						|
	var obj = {
 | 
						|
		context: context,
 | 
						|
		path: path,
 | 
						|
		request: request
 | 
						|
	};
 | 
						|
 | 
						|
	var localMissing;
 | 
						|
	var log;
 | 
						|
	var message = "resolve '" + request + "' in '" + path + "'";
 | 
						|
 | 
						|
	function writeLog(msg) {
 | 
						|
		log.push(msg);
 | 
						|
	}
 | 
						|
 | 
						|
	function logAsString() {
 | 
						|
		return log.join("\n");
 | 
						|
	}
 | 
						|
 | 
						|
	function onError(err, result) {
 | 
						|
		if(callback.log) {
 | 
						|
			for(var i = 0; i < log.length; i++)
 | 
						|
				callback.log(log[i]);
 | 
						|
		}
 | 
						|
 | 
						|
		if(err) return callback(err);
 | 
						|
 | 
						|
		var error = new Error("Can't " + message);
 | 
						|
		error.details = logAsString();
 | 
						|
		error.missing = localMissing;
 | 
						|
		resolver.applyPlugins("no-resolve", obj, error);
 | 
						|
		return callback(error);
 | 
						|
	}
 | 
						|
 | 
						|
	function onResolve(err, result) {
 | 
						|
		if(!err && result) {
 | 
						|
			return callback(null, result.path === false ? false : result.path + (result.query || ""), result);
 | 
						|
		}
 | 
						|
 | 
						|
		localMissing = [];
 | 
						|
		log = [];
 | 
						|
 | 
						|
		return resolver.doResolve("resolve", obj, message, createInnerCallback(onError, {
 | 
						|
			log: writeLog,
 | 
						|
			missing: localMissing,
 | 
						|
			stack: callback.stack
 | 
						|
		}));
 | 
						|
	}
 | 
						|
 | 
						|
	onResolve.missing = callback.missing;
 | 
						|
	onResolve.stack = callback.stack;
 | 
						|
 | 
						|
	return this.doResolve("resolve", obj, message, onResolve);
 | 
						|
};
 | 
						|
 | 
						|
Resolver.prototype.doResolve = function doResolve(type, request, message, callback) {
 | 
						|
	var resolver = this;
 | 
						|
	var stackLine = type + ": (" + request.path + ") " +
 | 
						|
		(request.request || "") + (request.query || "") +
 | 
						|
		(request.directory ? " directory" : "") +
 | 
						|
		(request.module ? " module" : "");
 | 
						|
	var newStack = [stackLine];
 | 
						|
	if(callback.stack) {
 | 
						|
		newStack = callback.stack.concat(newStack);
 | 
						|
		if(callback.stack.indexOf(stackLine) >= 0) {
 | 
						|
			// Prevent recursion
 | 
						|
			var recursionError = new Error("Recursion in resolving\nStack:\n  " + newStack.join("\n  "));
 | 
						|
			recursionError.recursion = true;
 | 
						|
			if(callback.log) callback.log("abort resolving because of recursion");
 | 
						|
			return callback(recursionError);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	resolver.applyPlugins("resolve-step", type, request);
 | 
						|
 | 
						|
	var beforePluginName = "before-" + type;
 | 
						|
	if(resolver.hasPlugins(beforePluginName)) {
 | 
						|
		resolver.applyPluginsAsyncSeriesBailResult1(beforePluginName, request, createInnerCallback(beforeInnerCallback, {
 | 
						|
			log: callback.log,
 | 
						|
			missing: callback.missing,
 | 
						|
			stack: newStack
 | 
						|
		}, message && ("before " + message), true));
 | 
						|
	} else {
 | 
						|
		runNormal();
 | 
						|
	}
 | 
						|
 | 
						|
	function beforeInnerCallback(err, result) {
 | 
						|
		if(arguments.length > 0) {
 | 
						|
			if(err) return callback(err);
 | 
						|
			if(result) return callback(null, result);
 | 
						|
			return callback();
 | 
						|
		}
 | 
						|
		runNormal();
 | 
						|
	}
 | 
						|
 | 
						|
	function runNormal() {
 | 
						|
		if(resolver.hasPlugins(type)) {
 | 
						|
			return resolver.applyPluginsAsyncSeriesBailResult1(type, request, createInnerCallback(innerCallback, {
 | 
						|
				log: callback.log,
 | 
						|
				missing: callback.missing,
 | 
						|
				stack: newStack
 | 
						|
			}, message));
 | 
						|
		} else {
 | 
						|
			runAfter();
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	function innerCallback(err, result) {
 | 
						|
		if(arguments.length > 0) {
 | 
						|
			if(err) return callback(err);
 | 
						|
			if(result) return callback(null, result);
 | 
						|
			return callback();
 | 
						|
		}
 | 
						|
		runAfter();
 | 
						|
	}
 | 
						|
 | 
						|
	function runAfter() {
 | 
						|
		var afterPluginName = "after-" + type;
 | 
						|
		if(resolver.hasPlugins(afterPluginName)) {
 | 
						|
			return resolver.applyPluginsAsyncSeriesBailResult1(afterPluginName, request, createInnerCallback(afterInnerCallback, {
 | 
						|
				log: callback.log,
 | 
						|
				missing: callback.missing,
 | 
						|
				stack: newStack
 | 
						|
			}, message && ("after " + message), true));
 | 
						|
		} else {
 | 
						|
			callback();
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	function afterInnerCallback(err, result) {
 | 
						|
		if(arguments.length > 0) {
 | 
						|
			if(err) return callback(err);
 | 
						|
			if(result) return callback(null, result);
 | 
						|
			return callback();
 | 
						|
		}
 | 
						|
		return callback();
 | 
						|
	}
 | 
						|
};
 | 
						|
 | 
						|
Resolver.prototype.parse = function parse(identifier) {
 | 
						|
	if(identifier === "") return null;
 | 
						|
	var part = {
 | 
						|
		request: "",
 | 
						|
		query: "",
 | 
						|
		module: false,
 | 
						|
		directory: false,
 | 
						|
		file: false
 | 
						|
	};
 | 
						|
	var idxQuery = identifier.indexOf("?");
 | 
						|
	if(idxQuery === 0) {
 | 
						|
		part.query = identifier;
 | 
						|
	} else if(idxQuery > 0) {
 | 
						|
		part.request = identifier.slice(0, idxQuery);
 | 
						|
		part.query = identifier.slice(idxQuery);
 | 
						|
	} else {
 | 
						|
		part.request = identifier;
 | 
						|
	}
 | 
						|
	if(part.request) {
 | 
						|
		part.module = this.isModule(part.request);
 | 
						|
		part.directory = this.isDirectory(part.request);
 | 
						|
		if(part.directory) {
 | 
						|
			part.request = part.request.substr(0, part.request.length - 1);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return part;
 | 
						|
};
 | 
						|
 | 
						|
var notModuleRegExp = /^\.$|^\.[\\\/]|^\.\.$|^\.\.[\/\\]|^\/|^[A-Z]:[\\\/]/i;
 | 
						|
Resolver.prototype.isModule = function isModule(path) {
 | 
						|
	return !notModuleRegExp.test(path);
 | 
						|
};
 | 
						|
 | 
						|
var directoryRegExp = /[\/\\]$/i;
 | 
						|
Resolver.prototype.isDirectory = function isDirectory(path) {
 | 
						|
	return directoryRegExp.test(path);
 | 
						|
};
 | 
						|
 | 
						|
var memoryFsJoin = require("memory-fs/lib/join");
 | 
						|
var memoizedJoin = new Map();
 | 
						|
Resolver.prototype.join = function(path, request) {
 | 
						|
	var cacheEntry;
 | 
						|
	var pathCache = memoizedJoin.get(path);
 | 
						|
	if(typeof pathCache === "undefined") {
 | 
						|
		memoizedJoin.set(path, pathCache = new Map());
 | 
						|
	} else {
 | 
						|
		cacheEntry = pathCache.get(request);
 | 
						|
		if(typeof cacheEntry !== "undefined")
 | 
						|
			return cacheEntry;
 | 
						|
	}
 | 
						|
	cacheEntry = memoryFsJoin(path, request);
 | 
						|
	pathCache.set(request, cacheEntry);
 | 
						|
	return cacheEntry;
 | 
						|
};
 | 
						|
 | 
						|
Resolver.prototype.normalize = require("memory-fs/lib/normalize");
 |