| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 | /*	MIT License http://www.opensource.org/licenses/mit-license.php	Author Tobias Koppers @sokra*/"use strict";const forEachBail = require("./forEachBail");const { PathType, getType } = require("./util/path");/** @typedef {import("./Resolver")} Resolver *//** @typedef {import("./Resolver").ResolveRequest} ResolveRequest *//** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook *//** @typedef {{alias: string|Array<string>|false, name: string, onlyModule?: boolean}} AliasOption */module.exports = class AliasPlugin {	/**	 * @param {string | ResolveStepHook} source source	 * @param {AliasOption | Array<AliasOption>} options options	 * @param {string | ResolveStepHook} target target	 */	constructor(source, options, target) {		this.source = source;		this.options = Array.isArray(options) ? options : [options];		this.target = target;	}	/**	 * @param {Resolver} resolver the resolver	 * @returns {void}	 */	apply(resolver) {		const target = resolver.ensureHook(this.target);		const getAbsolutePathWithSlashEnding = maybeAbsolutePath => {			const type = getType(maybeAbsolutePath);			if (type === PathType.AbsolutePosix || type === PathType.AbsoluteWin) {				return resolver.join(maybeAbsolutePath, "_").slice(0, -1);			}			return null;		};		const isSubPath = (path, maybeSubPath) => {			const absolutePath = getAbsolutePathWithSlashEnding(maybeSubPath);			if (!absolutePath) return false;			return path.startsWith(absolutePath);		};		resolver			.getHook(this.source)			.tapAsync("AliasPlugin", (request, resolveContext, callback) => {				const innerRequest = request.request || request.path;				if (!innerRequest) return callback();				forEachBail(					this.options,					(item, callback) => {						let shouldStop = false;						if (							innerRequest === item.name ||							(!item.onlyModule &&								(request.request									? innerRequest.startsWith(`${item.name}/`)									: isSubPath(innerRequest, item.name)))						) {							const remainingRequest = innerRequest.substr(item.name.length);							const resolveWithAlias = (alias, callback) => {								if (alias === false) {									/** @type {ResolveRequest} */									const ignoreObj = {										...request,										path: false									};									if (typeof resolveContext.yield === "function") {										resolveContext.yield(ignoreObj);										return callback(null, null);									}									return callback(null, ignoreObj);								}								if (									innerRequest !== alias &&									!innerRequest.startsWith(alias + "/")								) {									shouldStop = true;									const newRequestStr = alias + remainingRequest;									const obj = {										...request,										request: newRequestStr,										fullySpecified: false									};									return resolver.doResolve(										target,										obj,										"aliased with mapping '" +											item.name +											"': '" +											alias +											"' to '" +											newRequestStr +											"'",										resolveContext,										(err, result) => {											if (err) return callback(err);											if (result) return callback(null, result);											return callback();										}									);								}								return callback();							};							const stoppingCallback = (err, result) => {								if (err) return callback(err);								if (result) return callback(null, result);								// Don't allow other aliasing or raw request								if (shouldStop) return callback(null, null);								return callback();							};							if (Array.isArray(item.alias)) {								return forEachBail(									item.alias,									resolveWithAlias,									stoppingCallback								);							} else {								return resolveWithAlias(item.alias, stoppingCallback);							}						}						return callback();					},					callback				);			});	}};
 |